' !+JJJJ C\BD#,)=JJJ)AFAD r r х'+lB / X+L DD) +P `   ; A G :ž y! 4 5~yµ5 6y ’ ͒: ! OͻMD2 > BDOS ERR: $Seleh@(LH9LHH/Hh/ H-З( ܈(& ˆ$8 H` *HVDP (ED Z $0x8x D- ܈DD#>J>J>VU)?`8'x0|&HhHh VY)'&Y)xꪽ)' `Hh`V0^*^*>&` aI꽌ɪVɭ1  ͍ %͍͍ʢ͏͕!~# 4͕ ͍:g:s:_g:s!]~$o#~B̩1ɷW|g ͏͕%z͍͍ ͍vCPM3 SYS CPMLDR error: failed to open CPM3.SYS $ CPML!"*(+3111, ).*/ ./3 7??4##+#,,$$ 02<=-.,80^݌Hh Ì Ì݌ Ռ Ռ ՌA ČD Č? ČAEDE?HJ>h Ԍ Ռ Ռ Ռ`HJ>݌h Hh݌`  +JJJJDxǭLp . . T LeϠЯ͠ĠΠ͠ ALCDž=E<= BϠ  =B CL  =B =EAL>? >>?` =2x>!sGx!c8>Gͦ͞0 xGx(Gͦ͞0 xGx@Gͦx2:x22!x!px2 x>2!x>2"x>2#x.%.~ .~8 |&`ƀo66y .>H.yx (`(8` (24?949:4<  %%&&'''))*++++,,----...////23334556667777999:::;;;;<<====>>>????+8<(#!*?#>#0#0 >+/!#9!#:!.#&  &&'(((())***,,.000011112223444556 88889 : << >FG8`0($ p,&"_z]` L/慍ꅺL  !"#$%&'()*+,-./0123456789:;<=>?ct$Perm.$ v{_zW{_zW )8# ? w#JJ |^#V###" ##" ######" !  I* ! I* |! 6ʕ67 * w#w* w#w#w! ^#V#Fͪ' O* &! s#r#p* N#F* ^#V#F* : O}|y* %\8_* DMe - /:w9#/:w92\\B5:9 A/. ~9\ -9/!"5:}28>27>*ͥ.:x9Z^/. \": -f/.en* -v/:x9ʌ/:x92\\B5!"5:}2R>ͽ"d:`:d:͞8(0͹/H02DMv0 q*!Q>6h!Q>/:Q>=O! *d:Nq*:Q><2Q>/:R><2R>   y2 : xo&: W>O&E: N/* " y2 ʹ͗ͻͫʛ* X: O~Jyʔx ʍ ʂJÍNJ# h2 G>G:~X*  IOw!x>Fwx2 2 ~: : 6: w2 i - ` ` ` ` ` ` Ø ü ö ` ó ` ` ` Ô Ì b Í Ì Î Ì Ì Ó Í Ì Ì Ì Ì Ì :x*f +20282!_ "1""9- !y2) !f 0 ^#V" !`i`i"y2, `i"* > !r[2 x:* 2x:, 2x:x2x2x* +~p2+* .}|y#* %* DM"  * s#r* s#r#pyoxgkDM* 0 MD" ! * MD$ : O&! N:  yG>O: ʐÇ* ͒ : ʨn` ~#for2 O͚" }: O* 7" 2 " : O: G2 ! w*  * !~O !>w:ͨ2 4O.5Ϳ: ! S: ͮ: ͛ͳ: < =! wW* M_S -* MD:" : 2 ɯ2 >G=O* ~~w#~2 ~wc~~p2 !" >2 * ~=2 ~2 ͛o>* wx~2x !|2Ep}2Gp!psx: x7! "_>222028!_ "1"9! ":X 2ɯ!f ɉ a M /  ~2 ~2 : 2 : w: w |g}o' )4: O!3yoxg: O&}* : o$~w{ozg ^#V: ʏ> Û͡" ͳ* ç* r" ! ~#l [ I6: <!=6 * J " * K : G/O*  * =d ## I!" 2 =2 !" Û͛o͢͢' ͫ~<7 w@ͩ7: " Û: ~ : 2 : ~ * 6: p w#: w: w*@* }D> $* * T : _2 {20 q* q*0 q*̈́d:8+s#râ/ q* q*ͥ.!S>q> !S>O0:S>0Oq*Z0:S> AOq*!T>q:T>O60:T>O60!V>p+q*U>|O[0*U>}O[0*9>!=8"W>*W>!=8!Y>s:h0:Y>2h\͕60\>645*W>!=8!|s2*9͗8"9>. \~9 -0:9 1 h%"p86y5.50D1U LINK 1.31 $01/04/83?MEMRY$MEMRYX}CPMLDR COMbhMEMORY OVERFLOW, USE [A] SWITCH$INSUFFICIENT MEMORY$OVERLAPPING SEGMENTS$*[> 8+*[>##q#p*[>*[> N#F^#V?8*[> s#r *[> N#F`i"h>*[> N#F `i"j>*h>"f>j>f>͞8ڐ3*f>+*[> ^#V\8DM2_2*f>"f>\3*[> ^#V*j>\8DM2*[>  *[> ͞8Ҿ31*[> N#F*[> *[> N#F͏5!n>s+p+q*[>l>͠84 *[> ~.m9g97;   }INDEX ERROR$MULTIPLE DEFINITION: $MAIN MODULE ERROR$FIRST COMMON NOT LARGEST$COMMON ERR9ͫ8"|>##*|> ~!7!>6D7*>|?7!>66"|>D7!>6:>Y7!~>6#6#6Å7*|>~2~>*|> ~2>:>z7:>2>*|> ~2>!>6>!>ڰ7*>&v> ~/*>&: w!>4‹7:72"g:^ *:"|> *g:":*9My *9My *9My *~>My *>My **9>"9>\d5͍0C\͏5!Z>s*9>!=8C "9*9*|9s#r͍0C*Z>&\8DM\͔5:j2j\v5:9ҁ1*|9)8"|9:y9ZŠ1a9ҟ10ñ1g9ұ10!_>q.*[> :_>w*[> ~!`>q*[> :`>w*[> *[> ^#VN#FR* *[> 6*[fXXDATA $$$~XXCOMM $$$::;7;YYABS $$$YYPROG $$$YYDATA $$$YYCOMM $$$CPMLDR BPCPM3DR}ے}}}}?FPBNXBXXABS $$$ FXXPROG $$$4_2*l>DM2ͦ3Ê4*[>##l>͞8Ҋ4 *[> ~34_2*l>DM2:n>j4*[>  *[> N#FPY͹8d463g4ͦ3Ê4*[>  *[> ͞8҇41Ê4ͦ3!p>p+q*o>"[>!s>s+p+q*q>DM3*[> ^#V"]>*[> N#F*q>?8*]>:s>w *[> 6!u>p+q*t>DM3*[> ^#V"]>*[>OR$UNRECOGNIZED ITEM $ O}:F|: |1 >My *|>":i`N#Fog_og_{ozg_ogDM!>))덑o|gV8 =D8DM!>))k8 =c8_{ozg^#V) ~8^#V|g}o ˆ8_{ozgi`N#Fogo&og_{_z#W>^#V!=8"b>?8!a>s1!a>P2*[> DMv5*a>M1*[> DM͕6P2*[> DML5*b>!=8MͲ1*[>  *[> ͞8ҍ2*[>  *[> N#Fq#p *[> ~ڮ2*[> DMB5 *[> 61*[> N#F*[> *[> N#F͔51!e>p+q*[> N#F*d>?8^8*[>q#p*[>n;;;;      45*"6""6**6#"*6ú56**6?\ABORTED$NO SPACE$NO FILE: $CANNOT CLOSE$DISK READ ERROR: $DISK WRITE ERROR$YYYP   YP6YPYPYPYPYPYP Ͳ ò!>6#6͐6">*>|$7> N#F*t>?8*]>~   +5{>.+55OͲ5w66ͩ6́5;6<566́5͕6<>́5͕6<>645͜6<H66! w #ˆ5>Ö5>2,6""6"$6yo`"&6!"*6͋6-66*&6|6 "&6*"6MD6*$6DM:,65ͷ6g666Ͱ66**6|6U6*$6CPMBOOT1BINAPPLE HEXSCB ASM ALSCARD LIBZ80 LIBMCPM3 LIB  MAKBOOT3SUBREAD BAK#our source diskette on drive B:. Be sure that this is a copy of your programmers diskette #2 as it uses drive A: and B: as scratch area. Submit B:MAKBOOT3. This submit file will generate the files necessary to create the boot tracks. In the last step o  +JJJJDxǭLp . . T LeϠЯ͠ĠΠ͠ ALCDž=E<= BϠ  =B CL  =B =EAL>? >>?` =?@ABCDEPQ]^_ Lo <8M<E <Lo ϱ<ȅ= v *  M = v  Lo < =h=`HHH @ @L 8hhh`q<` <:x`gw: gw:0273B800FCFFD8 :0273DE00006449 :0373F200A70300EE :0000000000 0022A073219F03CD3573C922A4733245709F :1073980021A303CD3573C9AD0000608D000060A93D :1073A800628DF2038DF403A9FA8DF303AD82C06CEC ' !+JJJJ C\BD#,)=JJJ)AFAD r r х'+lB / X+L DD) +P `   XRWTS BINRSZBOOT BAK"UVWXYCOPYSYS COMZ[\ZBOOT HEXTSCB REL{CPM COM`opqrstuvwxyzALSBIOSCASMaabcdefghijklmMAKBOOT3BAKn:10730000C312734C5C03C38873C335734CA703C3A8 :107310009273F34F3A82603AFF6F7CFEC8DA34739F :10732000FED0D2347322D0733AF877C6A0672E000D :107330007E2AD0737922D0732ADE737CD6A0326E77 :107340007377002183607E7E3A4870473A467057D3 :107350003A47705F3A49704F3A4570:10000000003100012100507E2F77BE280F3AFF7883 :10001000D66032DF733EFF32FE783EFF210303CD10 :100020000073AF4711F8782100631AFE0338073ECA :1000300003B047CDA600CD9E00300C78E60317171D :10004000B01717B047180778F62847CDA600CD9E01 :1000500000300978E6030F0FB04718(24?949:4<  %%&&'''))*++++,,----...////23334556667777999:::;;;;<<====>>>????+8<(#!*?#>#0#0 >+/!#9!#:!.#&  &&'(((())***,,.000011112223444556 88889 : << >m,0d00 ?; submit file to create CPM CARD boot tracks rmac alsboot $$abrblbszpz-m link a:cpmldr=a:cpmldr,b:alsboot era b:alsboot.rel era a:cpmldr.sym sid J>J>VU)?`8'x0|&HhHh VY)'&Y)xꪽ)' `Hh`V0^*^*>&` aI꽌ɪVɭBMIT.CO CCP.CO RMAC.CO LINK.CO SID.COM BNKBDOS3.SPR RESBDOS3.SPR From Programmer's Kit Diskette number 1- GENCPM.COM GENCPM.DAT CPMLDR.REL Note: BNKBDOS3.SP an RESBDOS3.SP ar serialize file tha ar th "SOURCE" dis sinc i contain al th SOURCE an objec module needed A. CREATE THE MAKER DISK: 1. Use DSKCOP to format a blank diskette 2 Us PI t cop th followin file t you MAKER diskette: From distribution diskettes- SU!"*(+3111, ).*/ ./3 7??4##+#,,$$ 02<=-.,80^݌Hh Ì Ì݌ Ռ Ռ ՌA ČD Č? ČAEDE?HJ>h Ԍ Ռ Ռ Ռ`HJ>݌h Hh݌`clib alscard maclib z80 iobyte equ 3 public conin0,conout0,const0,conost0 public auxin0,auxout0,auxist0,auxost0 public list0,lstat0 public inictbl slot$table equ zpage+8f5h ;rick's table dseg ipchl: ;gets us to pchl and back to cain drive B: (Note- use copies, since A: and B: drives are used as scratch areas) 2. Type SUBMIT B:MAKBOOT3 (cr) 3. When prompted for destination drive, type A (cr) 4. When prompted about CPM3.SYS, answer N D. GENERATING NEW CPM3.SYS FILE 1. H8`?E Vk *f???0xE Hh D#-EEE8` D ܈x D - ܈x8`-0ݩ?ʥD EEE`   H+؅G`z firmin to firmout ; 8/3/83 aaconist,aaconi changed to use apread ; 8/8/83 if console is hs serial protocol, read ; apple keyboard status for constat ; on hs serial output status, always ready ; 8/9/83 on conout, convert adm3a codes to datamedia ; included with Revision B and higher software. If your system is Revision A, or was updated from Revision A to B, please check the distribution diskettes. If you do NOT have the files, please notify us with your specific seriHIHHHHhHH݌hHhHh݌H6  ȏHHH(jf5(  H Z(G FG HZXj 0x D$xxH` ( Zh ZL.xxH hBefore making any changes to the BIOS be sure you have read the CP/M PLUS System Guide and are familiar with it. file. steps A through D above, the diskette now in drive A: includes BIOS revision 3.01B1 and the corresponding CPM3.SYS file. Place the MAKER diskette in drive A: and SOURCE diskette in drive B: 2. Type SUBMIT MAKBIOS3 (cr) If you have followed steps A through D above, the diskette now in drive A: includes BIOS revision 3.01B1 and the corresponding CPM3.SYS file. In order to generate a new CPM system for the CPM CARD it is necessary to create 2 work disks. The first will be called the "MAKER" disk since it has all the programs on it needed to compile and generate the new system. The second disk is called 8/11/83 eliminate lda iobyte,(done in cseg that calls) ; eliminate BASIC protocol support ; 8/31/83 in firmware/serial out, don't do sta 678+n if not slot 3 ; 9/19/83 fixed RAL in IO16N to be ADD - GLW ; 9/20/83 added status check to ACMIN - GLW maal number, so that we may prepare a diskette for your system B. CREATE THE SOURCE DISK: Use DSKCOPY to make a copy of your programmers diskette #2. C. GENERATING BOOT TRACKS: 1. Place the MAKER diskette in drive A:, and SOURCE diskette h@(LH9LHH/Hh/ H-З( ܈(& ˆ$8 H` *HVDP (ED Z $0x8x D- ܈DD# title 'apple card utilities' ; filename=alscards.asm ; this program contains various routines for ; addressing card rom space ; character i/o operations ; 6/27/83 minor corrections, iobyte addr ; address addition ; 8/2/83 aserout change jrBMIT.COM CCP.COM RMAC.COM LINK.COM SID.COM BNKBDOS3.SPR RESBDOS3.SPR From Programmer's Kit Diskette number 1- GENCPM.COM GENCPM.DAT CPMLDR.REL Note: BNKBDOS3.SPR and RESBDOS3.SPR are serialized files that are the "SOURCE" disk since it contains all the SOURCE and object modules needed. A. CREATE THE MAKER DISK: 1. Use DSKCOPY to format a blank diskette 2. Use PIP to copy the following files to your MAKER diskette: From distribution diskettes- SUller pchl ; vectored character handlers conin0: genin: mvi b,2 ;indicate input jmp genvec ;go to general char routine auxin0: rar rar ;get auxin nibble jmp genin conorow: db 0 ;storage for row address conovec: dw conout1 ;vectECTOR FOR APREAD INX H INX H INX H SHLD RST5+1 ;SET UP RST VECTOR FOR APWRITE MVI A,JMPOP STA RST4 STA RST5 JMP 2D08H ;START WORDSTAR ; INTFCB: EQU $-PATCH2+INIT DB 0,'WS COM',0,0,0 DS 21 INTEND: EQU $ ; err22: lxi d,only3 ; for Banked BIOS (word, r/o) @CRDMA equ scb$base+3Ch ; Current DMA Address ; (word, r/o) @CRDSK equ scb$base+3Eh ; Current Disk (byte, r/o) @VINFO equ scb$base+3Fh ; BDOS Variable "INFO"conoquit conout20: cpi '*' jrnz conout2a ;not form-feed mvi c,0ch ;make it clr screen conout2b: call conoutn ;send char conout2b0: lxi h,conout1 ;restore normal vector jr conoquit conout2a: cpi 'Y' jrnz conout2c ;not vertical tab mvHour in BCD (byte, r/w) @MIN equ scb$base+5Bh ; Minute in BCD (byte, r/w) @SEC equ scb$base+5Ch ; Second in BCD (byte, r/w) ?ERJMP equ scb$base+5Fh ; BDOS Error Message Jump ; (word, r/w) @MXutput Redirection ; Vector (word, r/w) @AIVEC equ scb$base+26h ; Auxiliary Input Redirection ; Vector (word, r/w) @AOVEC equ scb$base+28h ; Auxiliary Output Redirection or to current process conout0: lhld conovec pchl ;vector to address conout1: mov a,c cpi 01bh jrnz conoutn ;not escape sequence, just output conoutnorm: lxi h,conout2 ;set up vector to analyze esc sequence conoquit: shld conovec ;updaCurrent User Code (byte, r/o) @mltio equ scb$base+4ah ; multi multi sector count ; byte r/w @ERMDE equ scb$base+4Bh ; BDOS Error Mode (byte, r/o) @erdsk equ scb$base+51h ; BDOS Error Disk (byte, r/o) @media equ scb$base+54h ; Set by BIOS t ; (word, r/o) @RESEL equ scb$base+41h ; FCB Flag (byte, r/o) @FX equ scb$base+43h ; BDOS Function for Error ; Messages (byte, r/o) @USRCD equ scb$base+44h ; title 'System Control Block Definition for CP/M3 BIOS' ; filename=scb.asm ;ver date detail ;1.0 4/17/83 add latest vectors from als public @civec, @covec, @aivec, @aovec, @lovec, @bnkbf public @crdma, @bflgs public @crdsk, @vinfo, @resel, @fx, TPA equ scb$base+62h ; Top of User TPA ; (address at 6,7)(word, r/o) end 3[b,q]=b:alsbiosc,b:alscards,b:scb gencpm auto display  ; Vector (word, r/w) @LOVEC equ scb$base+2Ah ; List Output Redirection ; Vector (word, r/w) @BNKBF equ scb$base+35h ; Address of 128 Byte Buffer te vector ret ;and return to caller conout2: ;prev char was esc, analyze curr char mov a,c cpi '=' jrnz conout20 ;not cursor address sequence mvi c,01eh ;send data media cursor prefix call conoutn lxi h,conout3 ;set for next phase jr o indicate ; open door (byte,r/w) @BFLGS equ scb$base+57h ; BDOS Message Size Flag (byte,r/o) @DATE equ scb$base+58h ; Date in Days Since 1 Jan 78 ; (word, r/w) @HOUR equ scb$base+5Ah ; ; console width @cnwdt equ scb$base+01ah ; same @conlen equ scb$base+01ch ; console length @CIVEC equ scb$base+22h ; Console Input Redirection ; Vector (word, r/w) @COVEC equ scb$base+24h ; Console O@usrcd, @ermde public @date, @hour, @min, @sec, ?erjmp, @mxtpa public @boot,@conwid,@cnwdt,@conlen public @mltio scb$base equ 0FE00H ; Base of the SCB @boot equ scb$base+13h ; drive # of cold boot device @conwid equ scb$base+01ah; ;; cpmcard library ;; 5/04/83 ;; 6/18/83 define clock values(62285, 1038) ;; 6/21/83 CROSS CORRELELATE LIBS WITH ALS ;; 6/23/83 make version a letter, lower case=alpha, ;; upper case=release version equ 62h ;'b' zpage equ 7000h ;location of apN ; LIXD NNNN LD IX,(NNNN) LIXD NNNN ; LIYD NNNN LD IY,(NNNN) LIYD NNNN ; SBCD NNNN LD (NNNN),BC SBCD NNNN ; SDED NNNN LD (NNNN),DE SDED NNNN ; SSPD NNNN LD (NNNN),SP SSPD NNNN ; SIXD NNNN LD (NNNN),IX SIXD NNNN ; SIYD NNNN LD (NNNN),IY SIYD cb equ ZPAGE+AIOCB ;Z-80 address of apple iocb rwts$tabl$type equ iocb rwts$slot equ iocb+1 rwts$drive equ iocb+2 rwts$volume equ iocb+3 rwts$trk equ iocb+4 rwts$sect equ iocb+5 rwts$char equ iocb+6 rwts$buf$adr equ iocb+8 rwts$null equ iocb+10 MB$XON$XOFF EQU 10H ;XON/XOF DEVICE FLAG CSW: EQU ZPAGE+036H ;OUTPUT VECTOR KSW: EQU ZPAGE+038H ;KEYBOARD VECTOR MSLOT: EQU ZPAGE+7F8H ;ACTIVE IO SLOT REMINDER (CNH) COUT: EQU 0FDEDH ;APPLE INDIRECT OUTPUT COUT1: EQU 0FDF0H ;APPLE 40 COLUMN PRINT ----- --- ; ; LDX R,D LD R,(IX+D) MOV R,D(IX) ; LDY R,D LD R,(IY+D) MOV R,D(IY) ; STX R,D LD (IX+D),R MOV D(IX),R ; STY R,D LD (IY+D),R MOV D(IY),R ; MVIX NN,D LD (IX+D),NN MVI D(IX) ; MVIY NN,D LD (IY+D),NN MVI D(IY) ; LDAI LD A,I LDApage+49h ;apple stack pointer applpc equ zpage+3d0h ;routine for apple to jsr to applio equ 06000h ;z80 addressing apple slot#0 io equ 0c000h ;apple base addr of apple slots applofs equ 9000h ;normal apple address offset from z80 rwts$buf equ zpageple $0000 off equ 0 on equ not off banked equ on cr equ 13 lf equ 10 bell equ 7 divisor equ 1038 ;scaled value of clock tick quotient equ 62285 ;#ticksper second*divisor @ctbl equ 0ff00h ;char device tbl in last page z80 ram @dvr$tbl$adr equ 0f (or type X to exit now' db ' without doing anything) $' mes6: DB 07H,0DH,0AH,'----- Cannot open "WS.COM" on drive B: -----' DB 0DH,0AH,07H,'$' ; ; NOTE: The table of addresses to modify is ordered from lower to higher ; cpmcrd: db 'CP/M CARD 'rwts$byte$count equ iocb+11 rwts$cmd equ iocb+12 ;00=seek ;01=read ;02=write ;03=format rwts$return$code equ iocb+13 rwts$lst$vol equ iocb+14 rwts$lst$slot equ iocb+15 rwts$lst$drv equ iocb+16  ACLEAR: EQU 0FC58H ;APPLE 40 COLUMN CLEARSCREEN rdkey: equ 0fd0ch ;standard apple kybd input KEYIN: EQU 0FD1BH ;APPLE KEYBOARD INPUT NCURSH: EQU ZPAGE+024H ;APPLE CURSOR HORIZONTAL NCURSV: EQU ZPAGE+025H ;APPLE CURSOR VERTICAL NBASL: EQU ZPAGE+02I ; LDAR LD A,R LDAR ; STAI LD I,A STAI ; STAR LD R,A STAR ; LXIX NNNN LD IX,NNNN LXI IX,NNNN ; LXIY NNNN LD IY,NNNN LXI IY,NNNN ; LBCD NNNN LD BC,(NNNN) LBCD NNNN ; LDED NNNN LD DE,(NNNN) LDED NNNN ; LSPD NNNN LD SP,(NNNN) LSPD NNN+200h ;rwts data buffer ; RWTS operation request codes rwts$rd$op equ 1 ;rwts read operation rwts$wr$op equ 2 ;rwts write operation rwts$seek$op equ 0 ;rwts seek operation rwts$format$op equ 4 ;rwts format operation ; RWTS relative IOCB addresses iof50h ;defined pointer to driver vectors @type$table equ 0ff80h ;slot relative tbl with card types ck$times$cd equ 32 ;# of times to read slot rom input equ 1 ;used only in chario out$put equ 2 ;used only in chario in$out equ 3 ;used only in chario ; ; Z-80 MACRO LIBRARY ; ; THE FOLLOWING MACROS ENABLE ASSEMBLING Z-80 INSTRUCTIONS ; WITH THE DIGITAL RESEARCH MACRO ASSEMBLER. ; ; INVOKE WITH "MACLIB Z80" ; ; ; ; MACRO FORMATS ; ----- ------- ; ; ; MACRO ZILOG TDL ; ----- APWRITE EQU APPLE+0FH ;APPLE MEMORY WRITE apple1 equ apple+9 ;apple starter doesn't kill add-ram appla equ zpage+45h ;apple a reg applx equ zpage+46h ;apple x reg apply equ zpage+47h ;apple y reg applst equ zpage+48h ;apple status reg applsp equ z8H ;APPLE CURSOR BASECALC NINVRS: EQU ZPAGE+032H ;APPLE VIDIO MASK (INVERSE,ETC) arwts equ 0870h ;apple address of rwts subroutine aiocb equ 0800h ;address of IOCB apple equ zpage+300h ;address of apple starter APREAD EQU APPLE+6 ;APPLE MEMORY READNNNN ; SPIX LD SP,IX SPIX ; SPIY LD SP,IY SPIY ; PUSHIX PUSH IX PUSH IX ; PUSHIY PUSH IY PUSH IY ; POPIX POP IX POP IX ; POPIY POP IY POP IY ; EXAF EX AF,AF' EXAF ; EXX EXX EXX ; XTIX EX (SP),IX XTIX ; XTIY EX (SP),IH,07BH DW ?NNNN ENDM LIXD MACRO ?NNNN DB 0DDH,2AH DW ?NNNN ENDM LIYD MACRO ?NNNN DB 0FDH,2AH DW ?NNNN ENDM SBCD MACRO ?NNNN DB 0EDH,43H DW ?NNNN ENDM SDED MACRO ?NNNN DB 0EDH,53H DW ?NNNN ENDM SSPD MACRO ?NNNN DB 0ED RLC (IY+D) RLCR D(IY) ; RALR R RL R RALR R ; RALX D RL (IX+D) RALR D(IX) ; RALY D RL (IY+D) RALR D(IY) ; RRCR R RRC R RRCR R ; RRCX D RRC (IX+D) RRCR D(IX) ; RRCY D RRC (IY+D) RRCR D(IY) ; RARR R RR R RARR R ; RARX D RR (IX+D) RAR XOR (IX+D) XRA D(IX) ; XORY D XOR (IY+D) XRA D(IY) ; ORX D OR (IX+D) ORA D(IX) ; ORY D OR (IY+D) ORA D(IY) ; CMPX D CP (IX+D) CMP D(IX) ; CMPY D CP (IY+D) CMP D(IY) ; INRX D INC (IX+D) INR D(IX) ; INRY D INC (IY+D) INR D(IY) ; DCRX DB 0FDH,70H+?R,?D ENDM MVIX MACRO ?N,?D @CHK ?D DB 0DDH,36H,?D,?N ENDM MVIY MACRO ?N,?D @CHK ?D DB 0FDH,36H,?D,?N ENDM LDAI MACRO DB 0EDH,57H ENDM LDAR MACRO DB 0EDH,5FH ENDM STAI MACRO DB 0EDH,47H ENDM STAR MACRO R-$ JRNC ADDR ; JRZ ADDR JR Z,ADDR-$ JRC ADDR ; JRNZ ADDR JR NZ,ADDR-$ JRNZ ADDR ; DJNZ ADDR DJNZ ADDR-$ DJNZ ADDR ; PCIX JMP (IX) PCIX ; PCIY JMP (IY) PCIY ; RETI RETI RETI ; RETN RETN RETN ; INP R IN R,(C) INP R ; OUTP R OUTY XTIY ; LDI LDI LDI ; LDIR LDIR LDIR ; LDD LDD LDD ; LDDR LDDR LDDR ; CCI CPI CCI ; CCIR CPIR CCIR ; CCD CPD CCD ; CCDR CPDR CCDR ; ADDX D ADD (IX+D) ADD D(IX) ; ADDY D ADD (IY+D) ADD D(IY) ; ADCX D ADC (IXRLX D SRL (IX+D) SRLR D(IX) ; SRLY D SRL (IY+D) SRLR D(IY) ; RLD RLD RLD ; RRD RRD RRD ; ; ; ; @CHK MACRO USED FOR CHECKING 8 BIT DISPLACMENTS ; @CHK MACRO ?DD ; USED FOR CHECKING RANGE OF 8-BIT DISP.S IF (?DD GT 7FH) AND (?DD LT 0FFR D(IX) ; RARY D RR (IY+D) RARR D(IY) ; SLAR R SLA R SLAR R ; SLAX D SLA (IX+D) SLAR D(IX) ; SLAY D SLA (IY+D) SLAR D(IY) ; SRAR R SRA R SRAR R ; SRAX D SRA (IX+D) SRAR D(IX) ; SRAY D SRA (IY+D) SRAR D(IY) ; SRLR R SRL R SRLR R ; SD INC (IX+D) INR D(IX) ; DCRY D DEC (IY+D) DCR D(IY) ; NEG NEG NEG ; IM0 IM0 IM0 ; IM1 IM1 IM1 ; IM2 IM2 IM2 ; DADC RR ADC HL,RR DADC RR ; DSBC RR SBC HL,RR DSBC RR ; DADX RR ADD IX,RR DADX RR ; DADY RR ADD IY,RR DADY R DB 0EDH,4FH ENDM LXIX MACRO ?NNNN DB 0DDH,21H DW ?NNNN ENDM LXIY MACRO ?NNNN DB 0FDH,21H DW ?NNNN ENDM LDED MACRO ?NNNN DB 0EDH,5BH DW ?NNNN ENDM LBCD MACRO ?NNNN DB 0EDH,4BH DW ?NNNN ENDM LSPD MACRO ?NNNN DB 0ED (C),R OUTP R ; INI INI INI ; INIR INIR INIR ; OUTI OTI OUTI ; OUTIR OTIR OUTIR ; IND IND IND ; INDR INDR INDR ; OUTD OTD OUTD ; OUTDR OTDR OUTDR ; RLCR R RLC R RLCR R ; RLCX D RLC (IX+D) RLCR D(IX) ; RLCY D +D) ADC D(IX) ; ADCY D ADC (IY+D) ADC D(IY) ; SUBX D SUB (IX+D) SUB D(IX) ; SUBY D SUB (IY+D) SUB D(IY) ; SBCX D SBC (IX+D) SBB D(IX) ; SBCY D SBC (IY+D) SBB D(IY) ; ANDX D AND (IX+D) ANA D(IX) ; ANDY D AND (IY+D) ANA D(IY) ; XORX D 80H) 'DISPLACEMENT RANGE ERROR - Z80 LIB' ENDIF ENDM LDX MACRO ?R,?D @CHK ?D DB 0DDH,?R*8+46H,?D ENDM LDY MACRO ?R,?D @CHK ?D DB 0FDH,?R*8+46H,?D ENDM STX MACRO ?R,?D @CHK ?D DB 0DDH,70H+?R,?D ENDM STY MACRO ?R,?D @CHK ?D ) BIT B,D(IY) ; SETX B,D SET B,(IX+D) SET B,D(IX) ; SETY B,D SET B,(IY+D) SET B,D(IY) ; RESX B,D RES B,(IX+D) RES B,D(IX) ; RESY B,D RES B,(IY+D) RES B,D(IY) ; JR ADDR JR ADDR-$ JMPR ADDR ; JRC ADDR JR C,ADDR-$ JRC ADDR ; JRNC ADDR JR NC,ADDR ; INXIX INC IX INX IX ; INXIY INC IY INX IY ; DCXIX DEC IX DCX IX ; DCXIY DEC IY DCX IY ; BIT B,R BIT B,R BIT B,R ; SETB B,R SET B,R SET B,R ; RES B,R RES B,R RES B,R ; BITX B,D BIT B,(IX+D) BIT B,D(IX) ; BITY B,D BIT B,(IY+DH,73H DW ?NNNN ENDM SIXD MACRO ?NNNN DB 0DDH,22H DW ?NNNN ENDM SIYD MACRO ?NNNN DB 0FDH,22H DW ?NNNN ENDM SPIX MACRO DB 0DDH,0F9H ENDM SPIY MACRO DB 0FDH,0F9H ENDM PUSHIX MACRO DB 0DDH,0E5H ENDM PUSHIY MACRO DB DB 0FDH, 0CBH, ?D, 16H ENDM RRCR MACRO ?R DB 0CBH, 08H + ?R ENDM RRCX MACRO ?D @CHK ?D DB 0DDH, 0CBH, ?D, 0EH ENDM RRCY MACRO ?D @CHK ?D DB 0FDH, 0CBH, ?D, 0EH ENDM RARR MACRO ?R DB 0CBH, 18H + ?R ENDM RARX MACRO ?D @CHK B 0CBH,?N*8+?R+40H ENDM SETB MACRO ?N,?R DB 0CBH,?N*8+?R+0C0H ENDM RES MACRO ?N,?R DB 0CBH,?N*8+?R+80H ENDM BITX MACRO ?N,?D @CHK ?D DB 0DDH,0CBH,?D,?N*8+46H ENDM BITY MACRO ?N,?D @CHK ?D DB 0FDH,0CBH,?D,?N*8+46H ENDM SETX MA ADDX MACRO ?D @CHK ?D DB 0DDH,86H,?D ENDM ADDY MACRO ?D @CHK ?D DB 0FDH,86H,?D ENDM ADCX MACRO ?D @CHK ?D DB 0DDH,8EH,?D ENDM ADCY MACRO ?D @CHK ?D DB 0FDH,8EH,?D ENDM SUBX MACRO ?D @CHK ?D DB 0DDH,96H,?D ENDM SUBY ENDM IND MACRO DB 0EDH,0AAH ENDM INDR MACRO DB 0EDH,0BAH ENDM OUTI MACRO DB 0EDH,0A3H ENDM OUTIR MACRO DB 0EDH,0B3H ENDM OUTD MACRO DB 0EDH,0ABH ENDM OUTDR MACRO DB 0EDH,0BBH ENDM RLCR MACRO ?R DB 0CBH, 00DB 0EDH,44H ENDM IM0 MACRO DB 0EDH,46H ENDM IM1 MACRO DB 0EDH,56H ENDM IM2 MACRO DB 0EDH,5EH ENDM BC EQU 0 DE EQU 2 HL EQU 4 IX EQU 4 IY EQU 4 DADC MACRO ?R DB 0EDH,?R*8+4AH ENDM DSBC MACRO ?R DB 0EDH,?R*8+42H 0FDH,0E5H ENDM POPIX MACRO DB 0DDH,0E1H ENDM POPIY MACRO DB 0FDH,0E1H ENDM EXAF MACRO DB 08H ENDM EXX MACRO DB 0D9H ENDM XTIX MACRO DB 0DDH,0E3H ENDM XTIY MACRO DB 0FDH,0E3H ENDM LDI MACRO DB 0EDH,0A0H O ?N DB 18H,?N-$-1 ENDM JRC MACRO ?N DB 38H,?N-$-1 ENDM JRNC MACRO ?N DB 30H,?N-$-1 ENDM JRZ MACRO ?N DB 28H,?N-$-1 ENDM JRNZ MACRO ?N DB 20H,?N-$-1 ENDM DJNZ MACRO ?N DB 10H,?N-$-1 ENDM PCIX MACRO DB 0DDH,0E9H ENDM PCRO ?N,?D @CHK ?D DB 0DDH,0CBH,?D,?N*8+0C6H ENDM SETY MACRO ?N,?D @CHK ?D DB 0FDH,0CBH,?D,?N*8+0C6H ENDM RESX MACRO ?N,?D @CHK ?D DB 0DDH,0CBH,?D,?N*8+86H ENDM RESY MACRO ?N,?D @CHK ?D DB 0FDH,0CBH,?D,?N*8+86H ENDM JR MACRMACRO ?D @CHK ?D DB 0FDH,96H,?D ENDM SBCX MACRO ?D @CHK ?D DB 0DDH,9EH,?D ENDM SBCY MACRO ?D @CHK ?D DB 0FDH,9EH,?D ENDM ANDX MACRO ?D @CHK ?D DB 0DDH,0A6H,?D ENDM ANDY MACRO ?D @CHK ?D DB 0FDH,0A6H,?D ENDM XORX MACRH + ?R ENDM RLCX MACRO ?D @CHK ?D DB 0DDH, 0CBH, ?D, 06H ENDM RLCY MACRO ?D @CHK ?D DB 0FDH, 0CBH, ?D, 06H ENDM RALR MACRO ?R DB 0CBH, 10H+?R ENDM RALX MACRO ?D @CHK ?D DB 0DDH, 0CBH, ?D, 16H ENDM RALY MACRO ?D @CHK ?D ENDM DADX MACRO ?R DB 0DDH,?R*8+09H ENDM DADY MACRO ?R DB 0FDH,?R*8+09H ENDM INXIX MACRO DB 0DDH,23H ENDM INXIY MACRO DB 0FDH,23H ENDM DCXIX MACRO DB 0DDH,2BH ENDM DCXIY MACRO DB 0FDH,2BH ENDM BIT MACRO ?N,?R DENDM LDIR MACRO DB 0EDH,0B0H ENDM LDD MACRO DB 0EDH,0A8H ENDM LDDR MACRO DB 0EDH,0B8H ENDM CCI MACRO DB 0EDH,0A1H ENDM CCIR MACRO DB 0EDH,0B1H ENDM CCD MACRO DB 0EDH,0A9H ENDM CCDR MACRO DB 0EDH,0B9H ENDM CIY MACRO DB 0FDH,0E9H ENDM RETI MACRO DB 0EDH,4DH ENDM RETN MACRO DB 0EDH,45H ENDM INP MACRO ?R DB 0EDH,?R*8+40H ENDM OUTP MACRO ?R DB 0EDH,?R*8+41H ENDM INI MACRO DB 0EDH,0A2H ENDM INIR MACRO DB 0EDH,0B2H D @CHK ?D DB 0FDH,0BEH,?D ENDM INRX MACRO ?D @CHK ?D DB 0DDH,34H,?D ENDM INRY MACRO ?D @CHK ?D DB 0FDH,34H,?D ENDM DCRX MACRO ?D @CHK ?D DB 0DDH,035H,?D ENDM DCRY MACRO ?D @CHK ?D DB 0FDH,35H,?D ENDM NEG MACRO O ?D @CHK ?D DB 0DDH,0AEH,?D ENDM XORY MACRO ?D @CHK ?D DB 0FDH,0AEH,?D ENDM ORX MACRO ?D @CHK ?D DB 0DDH,0B6H,?D ENDM ORY MACRO ?D @CHK ?D DB 0FDH,0B6H,?D ENDM CMPX MACRO ?D @CHK ?D DB 0DDH,0BEH,?D ENDM CMPY MACRO ??D DB 0DDH, 0CBH, ?D, 1EH ENDM RARY MACRO ?D @CHK ?D DB 0FDH, 0CBH, ?D, 1EH ENDM SLAR MACRO ?R DB 0CBH, 20H + ?R ENDM SLAX MACRO ?D @CHK ?D DB 0DDH, 0CBH, ?D, 26H ENDM SLAY MACRO ?D @CHK ?D DB 0FDH, 0CBH, ?D, 26H ENDM SRAtem tracks db ?psh,?psm ; physical sector size shift ; and mask endm ; gcd macro ?m,?n ;; greatest common divisor of m,n ;; produces value gcdn as result ;; (used in sector translate table generation) ?gcdm set ?m ;cb, dtabcb, hash alloc'd ; by GENCPM db 0 ; hash bank if not nul ?csize ?csv ds ?csize ; checksum vector endif if not nul ?asize ?alv ds ?asize ; allocation vector endif endm dpb macro ?psize,?pspt,?trks,?bls,?nRZ LHLD TRACK INX H SHLD TRACK SHLD BCREG MVI A,SETTRK STA FUNC MVI C,DBIOS LXI D,BIOSPB CALL BDOS XRA A RET CHKTRK: LHLD TRACK MVI A,(MAXTRK) /100H SUB H MOV C,A MVI A,(MAXTRK) AND 0FFH SUB L ORA C RNZ XRA A RET set (?ndirs*32+?bls-1)/?bls rept ?n ?all set (?all shr 1) or 8000h endm ?al0 set high ?all ?al1 set low ?all ?drm set ?ndirs-1 if not nul ?ncks ?cks set ?ncks else ?cks set ?ndirs/4 endif dw ?spt ; 128 byte r 0 endm endif endm dph macro ?trans,?dpb,?csize,?asize local ?csv,?alv dw ?trans ; translate table address db 0,0,0,0,0,0,0,0,0 ; BDOS Scratch area db 0 ; media flag dw ?dpb ; disk parameter block if not nul ?csize dw ?R MACRO ?R DB 0CBH, 28H+?R ENDM SRAX MACRO ?D @CHK ?D DB 0DDH, 0CBH, ?D, 2EH ENDM SRAY MACRO ?D @CHK ?D DB 0FDH, 0CBH, ?D, 2EH ENDM SRLR MACRO ?R DB 0CBH, 38H + ?R ENDM SRLX MACRO ?D @CHK ?D DB 0DDH, 0CBH, ?D, 3EH ENDM Stm endif ?psh set ?psh + 1 endm ?spt set ?pspt*(?psize/128) ?bsh set 3 ?n set ?bls/1024 rept 8 ?n set ?n/2 if ?n = 0 exitm endif ?bsh set ?bsh + 1 endm ?blm set ?bls/128-1 ?size set (?trks-?ofdirs,?off,?ncks local ?spt,?bsh,?blm,?exm,?dsm,?drm,?al0,?al1,?cks,?psh,?psm local ?n ;; physical sector mask and physical sector shift ?psh set 0 ?n set ?psize/128 ?psm set ?n-1 rept 8 ?n set ?n/2 if ?n = 0 exi; Macro Definitions for CP/M3 BIOS Data Structures. ; dtbl - drive table ; dph translate$table, - disk parameter header ; disk$parameter$block, ; checksum$size, (optional) ; alloc$size (optional) ; skew sectors, - skecords per track db ?bsh,?blm ; block shift and mask db ?exm ; extent mask dw ?dsm ; maximum block number dw ?drm ; maximum directory entry number db ?al0,?al1 ; alloc vector for directory dw ?cks ; checksum size dw ?off ; offset for syscsv ; checksum vector else dw 0FFFEh ; checksum vector allocated by endif ; GENCPM if not nul ?asize dw ?alv ; allocation vector else dw 0FFFEh ; alloc vector allocated by GENCPM endif dw 0fffeh,0fffeh,0fffeh ; dirbRLY MACRO ?D @CHK ?D DB 0FDH, 0CBH, ?D, 3EH ENDM RLD MACRO DB 0EDH, 6FH ENDM RRD MACRO DB 0EDH, 67H ENDM cb+13 rwts$lst$vol equ iocb+14 rwts$lst$slot equ iocb+15 rwts$lst$drv equ iocb+16 f)*?spt ?dsm set ?size/(?bls/128)-1 ?exm set ?bls/1024 if ?dsm > 255 if ?bls = 1024 .'Error, can''t have this size disk with 1k block size' exitm endif ?exm set ?exm/2 endif ?exm set ?exm-1 ?all set 0 ?n rive Table. Contains 16 one word entries. dtbl macro ?list local ?n ?n set 0 irp ?drv, ?n set ?n+1 dw ?drv endm if ?n > 16 .' Too many drives. Max 16 allowed' exitm endif if ?n < 16 rept (16-?n) dwew table ; skew$factor, ; first$sector$number ; dpb physical$sector$size, - disk parameter block ; physical$sectors$per$track, ; number$tracks, ; block$size, ; number$dir$entries, ; track$offset, ; checksum$vec$size (optional) ; D;variable for m ?gcdn set ?n ;;variable for n ?gcdr set 0 ;;variable for r rept 65535 ?gcdx set ?gcdm/?gcdn ?gcdr set ?gcdm - ?gcdx*?gcdn if ?gcdr = 0 exitm endif ?gcdm set ?gcdn ?gcdn set ?gcdr endm endm skeBefor makin an change t th BIO b sur yo hav rea th CP/ PLU Syste Guid an ar familia wit it. 0022A073219F03CD3573C922A4733245709F :1073980021A303CD3573C9AD0000608D000060A93D :1073A800628DF2038DF403A9FA8DF303AD82C06CEC h@(LH9LHH/Hh/ H-З( ܈(& ˆ$8 H` *HVDP (ED Z $0x8x D- ܈DD# set ?nelts-1 if ?nelts = 0 ?nxtbas set ?nxtbas+1 ?nxtsec set ?nxtbas ?nelts set ?neltst endif endm endm i driv B (Note- us copies sinc A an B drive ar use a scratch areas) 2. Type SUBMIT B:MAKBOOT3 (cr) 3. When prompted for destination drive, type A (cr) 4. When prompted about CPM3.SYS, answer N D. GENERATING NEW CPM3.SYS FILE 1d h dad h ;develop address of jmp in tbl dad d mov e,m inx h mov d,m xchg pchl ;get address and go to it auxout0: rar rar rar rar jmp genout list0: rlc rlc jmp genout const0: genist: mvi b,4 ;offset for status w macro ?secs,?skf,?fsc ;; generate the translate table ?nxtsec set 0 ;;next sector to fill ?nxtbas set 0 ;;moves by one on overflow gcd %?secs,?skf ;; ?gcdn = gcd(?secs,skew) ?neltst set ?secs/?gcdn ;; neltst is number of elsL\Ès5sLÒsO:`:o|4s4s"s:wƠg.~*sy"s*s|֠2nsw!`~~:HpG:FpW:Gp_:IpO:EpxFGEhHIFGHHE( L\l"s!5s"s2Ep!5sɭ``bld H8`?E Vk *f???0xE Hh D#-EEE8` D ܈x D - ܈x8`-0ݩ?ʥD EEE`   H+؅G`i c,0bh jz conout2b ;send it conout2c: cpi 'T' jrnz conout2b0 ;invalid, ignore mvi c,01dh ;send gs(clr to end of line) jr conout2b ;send it and set normal mode conout3: mov a,c sta conorow ;save row address lxi h,conout4 ;set for next p Plac th MAKER diskett i driv A an SOURCE diskett i drive B: 2. Type SUBMIT MAKBIOS3 (cr) I yo hav followe step throug above th diskett no i driv A include BIO revisio 3.01B an th correspondin CPM3.SYS file. HIHHHHhHH݌hHhHh݌H6  ȏHHH(jf5(  H Z(G FG HZXj 0x D$xxH` ( Zh ZL.xxH hements to generate ;; before we overlap previous elements ?nelts set ?neltst ;;counter rept ?secs ;;once for each sector db ?nxtsec+?fsc ?nxtsec set ?nxtsec+?skf if ?nxtsec >= ?secs ?nxtsec set ?nxtsec-?secs endif ?neltsa number s tha w ma prepar diskett fo you system B. CREAT TH SOURC DISK: Us DSKCOP t mak cop o you programmer diskett #2 C. GENERATING BOOT TRACKS: 1 Plac th MAKER diskett i driv A: an SOURCE diskett d,0 char$vec: lxi h,slot$table dad d mov a,m ;get protocol type sta mtype ;save type of protocol char$vec$1: lxi h,dvr$tbl mov e,b mvi d,0 dad d ;offset table for function xchg mov l,a dad h ;offset * 8 for card position dahase jr conoquit conout4: call conoutn ;send column lda conorow mov c,a jr conout2b ;send it and set normal mode conoutn: lda iobyte genout: mvi b,0 ;offset to output routine genvec: ani 3 sta mslot ;save slot # mov e,a mvi1!P~/w(:x`2s>2x>!sGx!c8>Gͦ͞0 xGx(Gͦ͞0 xGx@Gͦx2:x22!x!px2 x>2!x>2"x>2#x.%.~ .~8 |&`ƀo66y .>H.yx (`(8` always output=ready status mvi a,10h call aserio mvi a,0 ;output status rqst sta appla call apple mov a,b ani 1 rz mvi a,0ffh ret ; apple serial/firmware input aserin: mvi a,0eh call aserio lda mtype cpi 3 jrz firmin ;r slot working mtype: db 0 ;for protocol type zion00: ;generate z80 relative card rom address ; based on mslot=slot# lxi h,applio ion00: lda mslot ora h mov h,a ret zio0n0: ;generate relative z80 x0n0 address lxi h,applio ; A G :ž y! 4 5~yµ5 6y ’ ͒: ! OͻMD2 > BDOS ERR: $Seleget offset byte pop h ;reget CN00 mov l,b ret ; apple serial/firmware status check aserstin: ;input status check lda mtype cpi 4 jrnz aserstin1 ;not hs serial lda mslot cpi 3 jz aaconist ;if slot 3&hsserial,use kybd status asers  y2 : xo&: W>O&E: N/* " y2 ʹ͗ͻͫʛ* X: O~Jyʔx ʍ ʂJÍNJ# h2 G>G:~X*  IOw!x>Fwx2 2 ~: : 6: w2 1  ͍ %͍͍ʢ͏͕!~# 4͕ ͍:g:s:_g:s!]~$o#~B̩1ɷW|g ͏͕%z͍͍ ͍vCPM3 SYS CPMLDR error: failed to open CPM3.SYS $ CPMLgenerate apple C0N0h address lxi h,0c000h jmp io16n aplio0NE: ;generate apple C0NEh address lxi h,0c08eh jmp io16n ; serial and firmware preparation subroutine aserio: ;enter areg=function offset mov b,a lda applio+0fffh ;turn ofio16n: ;generate 16 * slot # lda mslot add a add a add a add a ora l mov l,a ret zio0ne: ;generate z80 x0NEh address lxi h,applio+8eh jmp io16n aplion00: ;generate apple CN00h address lxi h,0c000h jmp ion00 aplio0n0 ;ct$Perm.$ v{_zW{_zW )8# ? w#JJ |^#V###" ##" ######" !  I* ! I* |! 6ʕ67 * w#w* w#w#w! ^#V#Fͪ' O* &! s#r#p* N#F* ^#V#F* : O}|y* %tin1: mvi a,10h call aserio mvi a,1 ;input status rqst sta appla call apple mov a,b ;apple cy ani 1 rz aserinrdy: mvi a,0ffh ret ; apple serial/firmware output status check aserstou: lda mtype cpi 4 jrz aserinrdy ;type 4 jmp genvec lstat0: rlc rlc genost: mvi b,6 ;offset for status out jmp genvec auxist0: rar rar rar rar jmp genist auxost0: rar rar rar rar jmp genost conost0: jmp genost max$devices equ 8 mslot: db 0 ;foDR error: failed to read CPM3.SYS $ CP/M V3.0 Loader Copyright (C) 1982, Digital Research $021182" yڥ2 2 : 2 {2 !" " 9"@1!N y2K!dڛ_^#V*    f any other cards call aplio0n0 ;get c0n0 sta zpage+6f8h ;really wanted 16*n in areg sta apply call aplion00 ;get cn00 sta zpage+07f8h ;set apple's slot# sta applx push h call zion00 ;get 6N00 mov a,m ;select card mov l,b mov b,m ;~2 ~2 : 2 : w: w |g}o' )4: O!3yoxg: O&}* : o$~w{ozg ^#V: ʏ> Û͡" ͳ* ç* r" ! ~#O: ʐÇ* ͒ : ʨn` ~#for2 O͚" }: O* 7" 2 " : O: G2 ! w*  * !use firmware proto lxi h,0c84dh ;use hs serial proto firmin: call apple lxi h,zpage+678h ;get data from 678+n lda mslot add l mov l,a mov a,m ;actually get character ret ; apple serial/firmware output aserout: mvi a,0fh call ase ; ROUTINES FOR INITIALIZING DEVICES AACONINI: RET ;last$chr$tbl: ;keeps track of each card's last output char ; db 0,0,0,0 ; db 0,0,0,0 cseg ini$ctbl: db 0 ;kill any table ;prototype CHARACTER I/O TABLE ; db ' APCON',IN$OUT,0 ; anrdy: ;always not ready status xra a ret AEOF: ;ALWAYS RETURN EOF ON INPUT MVI A,01AH ARET: ;ALWAYS RETURN (NULL OUTPUT) RET ; APPLE CONSOLE ROUTINES ; ********invoke below only when sure it all works as bios3 AACONO: ;ready, so wait call zio0n0 mov a,l ori 80h ;make it io+0n0+80h mov l,a mov m,c ;put the char ret ; apple com interface card routines acminst: ;com input status call zio0ne ;get i/o base +8eh +16*slot mov a,m ani 1 rz ;not ready CALL APPLE ;A=CHARACTER, HL=ROMOUT ret AACONIST: ;APPLE CONSOLE INPUT STATUS lxi h,io call apread ;use apple read ral mvi a,0ffh jrc cistnd ;char rdy, restore bank&stack xra a cistnd: ora a ret AACONI: ;APPLE CONSOLE INPlastchar ; rz ;dont output lf after cr ; call aplion00 ; mvi l,5 ; mov a,c ; call apple ; ret ;othin: ; call aplion00 ; mvi l,7 ; call apple ; ret ;lastchar: ; lxi h,last$chr$tbl ; lda mslot ; mov e,a ; mvi d,0 ; dad d ;gen addr thirio mov a,c sta appla lda mtype cpi 3 jrz firmout ;use firmware proto lxi h,zpage+678h ;generate where to put data lda mslot add l mov l,a mov m,c ;put it lxi h,0c9aah ;use hs serial proto firmout: call apple ret aparoust: MOV H,A LDA NCURSH ;ALSO GET THE 'X' POSITION ADD L MOV L,A ;HL NOW HAS THE CURRENT Z80 CURSOR ADDRESS MOV A,M XRI 0C0H ;FLIP THE FLASHING BIT (FOR A CURSOR) MOV M,A RET ;ACTUALLY PERFORM THE PRINT FUNCTION NCONOU: mov a,c CPI CAPPLE CONSOLE OUTPUT ;** APPLE 40 COLUMN DRIVER ** nconout: CALL NCURS ;TURN THE CURSOR OFF CALL NCONOU ;PRINT THE CHARACTER call ncurs ret NCURS: LHLD NBASL ;GET THE NEW CURSOR 'Y' POSITION MOV A,H ORI ZPAGE/100H ;MAKE IT A Z80 ADDRESS mvi a,0ffh ;ready ret acmoust: ;com output status call zio0ne ;get i/o base + 8eh +16*slot mov a,m ani 2 rz ;not ready mvi a,0ffh ;ready ret acmin: ;input com data call acminst jrz acmin call zio0ne ;get i/o base + 8eh +16*sUT call aaconist ;check status jrz aaconi ;not ready lxi h,io call apread ;use apple read push psw lxi h,io+10h call apread ;hit the strobe pop psw ; LXI H,0fd21h ;(keyin2) ; CALL APPLE ;HAVE APPLE READ THE KEY ani 07fh ret s card's last char ; mov a,m ;get last char ; mov m,c ;store new last char ; cpi 0dh ; rnz ;if last ne cr, ignore ; mov a,c ;last = cr, get curr ; cpi 0ah ; ret ;flag if lf after cr ARDY: ;ALWAYS READY STATUS ROUTINE MVI A,0FFH ret ;old apple parallel printer status driver call zion00 mvi l,0c1h mov a,m cma ;status bit to cy and bit 0 ani 80h rz ;not ready ori 0ffh ret ;ready aparout: ;old apple aprallel printer output driver call aparoust jrz aparout ;not R JNZ NCONOU1 ;IF NOT CARR RETURN XRA A STA ZPAGE +24H ;ON CARR RET SET CURSOR TO LEFT MARG RET NCONOU1: mov A,c ORI 80H ;SET THE HI BIT CPI 80H+'`' ;LOWER CASE? JC NCONO1 SUI 20H ;FORM UPPER CASE NCONO1: STA APPLA LXI H,COUT1 init pcb and change table entry ;othini: ; call lastchar ;elim lf after cr on basic proto ; call aplion00 ;use init to output first char ; mov a,c ; call apple ; lxi h,othout ; shld othent ;change pointer to use output ; ret ;othout: ; call lot inx h ;h=608eh +slot*16+1 mov a,m ;get data ret acmout: ;output com data call acmoust jrz acmout call zio0ne ;get i/o base + 8eh +16*slot inx h ;h=608eh+slot*16+1 mov m,c ;output data ret ; basic protocol ; on first entry, ;ini$ent$len equ $-ini$ctbl ;specify length of entry ; ; first byte in entry becomes slot # ; ; DB ' PARLL',OUT$PUT,0 ; DB ' FIRM ',IN$OUT,0 ; DB ' COMM ',IN$OUT,0 ; DB ' HSSER',IN$OUT,0 ; DB ' DISK ',0,0 ; DB ' NOTYP',0,0 ; DB ' EMPTY',0,0 ; DB!" 2 =2 !" Û͛o͢͢' ͫ~<7 w@ͩ7: " Û: ~ : 2 : ~ * 6: p w#: w: w*@* }D> $* * T : _2 {2] 8%87y2]8~#z0 0!]_w!]~B84_!]s4V4V2]G:]<2]=4V:]4Vͨ8€8:]ʀ8!]5!]44V:]G:]ʎ8!]I8>2]8=!]5š8:]!]<_!]>w w>+ý8!]~5>.9G:]x08:]> !]~85!]4!]5-2 l2 \r6Fy@D9NPh(o:!k'C@C( dhn2#) )JR8 %#!.ӝO7Ͷ mxruVٶ=6mD5m# BOWpͶ` D/,h>a2C >pC@@s @pemf ' CPM ',0,0 dseg DVR$TBL: ;DRIVER RELATIVE TABLE DW AACONO,AACONI,AACONIST,ARDY ;ALWAYS APPLCON rept 2 DW ARET,AEOF,ARDY,ARDY ;types 1&2 ENDM DW ASEROUT,ASERIN,aserstin,aserstou ;type 3 DW ASEROUT,ASERIN,aserstin,aserstou ;type 4 i - ` ` ` ` ` ` Ø ü ö ` ó ` ` ` Ô Ì b Í Ì Î Ì Ì Ó Í Ì Ì Ì Ì Ì :x*f +20282!_ "1""9- !y2) !f 0 ^#V" !`i`i"y2, `i"* > !r[2 x:* 2x:, 2x:x2x2x* +~p2 " r" [  ?, d >l [ I6: <!=6 * J " * K : G/O*  * =d ## I; submit file to make a cpm3 system rmac alsbiosc $$abrblbszpz-m rmac alscards $$abrblbszpz-m rmac scb $$abrblbszpz-m link bnkbios3[b,q]=b:alsbiosc,b:alscards,b:scb era b:alsbiosc.rel era b:alscards.rel era b:scb.rel gencpm auto display era bnkbio~O !>w:ͨ2 4O.5Ϳ: ! S: ͮ: ͛ͳ: < =! wW* M_S -* MD:" : 2 ɯ2 >G=O* ~~w#~2 ~wc~~p2 !" >2 * ~=2 ~2 ͛o>* w ; basic protocol currently not supported othent: dw aret,aeof,ardy,ardy ;type 5 DW ACMOUT,ACMIN,ACMINST,ACMOUST ;type 6 dw aparout,aeof,ardy,aparoust ;type 7 end t: dw aret,aeof,ardy,ardy ;type 5 DW ACMOUT,ACMIN,ACMINST,ACMOUST ;type x~2x !|2Ep}2Gp!psx: x7! "_>222028!_ "1"9! ":X 2ɯ!f ɉ a M /  O#,H2Gn`@ :kvv`dUp5@'j|2Yd<G@F+?9 Gn>dw5l vU\ mpVͶ HFmX6ۀ8X,qx}!9 t <-@{?s( \  Ps3.spr era bnkbios3.sym lscards,b:scb era b:alsbiosc.rel era b:alscards.rel era b:scb.rel gencpm auto display era bnkbionkbios3[b,q]=b:alsbiosc,b:alscards,b:scb era b:alsbiosc.rel era b:alscards.rel era b:scb.rel gencpm auto display era bnkbioVE TRANSLATION MOV L,C RET SETDMA: MOV H,B MOV L,C SHLD DMAAD RET SETSEC: MOV A,C STA SECT RET HOME: LXI B,0 ;LET SETTRK DO THE ZEROING SETTRK: MOV H,B MOV L,C SHLD TRACK RET READ: mvi a,1 call rwcommon rnz ;erro EQU 3 SWAPPER: EQU 10H ;AB/CD DISK DRIVE MAPPING (NONZERO=NORMAL) BIOS: EQU $ JMP BOOT WBOOTE: JMP WBOOT JMP CONST JMP CONIN JMP CONOUT JMP LIST JMP auxout JMP auxin JMP HOME JMP SELDSK JMP SETTRK JMP SETSEC JMP SETDMA JM  y2 : xo&: W>O&E: N/* " y2 ʹ͗ͻͫʛ* X: O~Jyʔx ʍ ʂJÍNJ# h2 G>G:~X*  IOw!x>Fwx2 2 ~: : 6: w2 DEVTBL: lxi h,0 RET *** LOGICAL DISK DRIVERS *** ;ALL PHYSICAL OPERATIONS ARE POSTPONED TILL READ/WRITE ;INTERNALLY, DISKS 0&1 ARE FLOPPY, 2&3 ARE HARD SELDSK: MOV A,C sta disk mvi b,0 lxi h,dsktbl ;use table to find dph cpi 16 EQU 0800H ;6502 ADDRESS OF IOCB IOCB: EQU ZPAGE+AIOCB ;Z80 ADDRESS OF IOCB IOCBSL: EQU IOCB+ 1 ;SLOT*10# (usually 50 OR 60H) IOCBD: EQU IOCB+ 2 ;DRIVE# (1-2) IOCBV: EQU IOCB+ 3 ;VOLUME# (floppies are 00) IOCBT: EQU IOCB+ 4 ;TRACK# (00-22H) IOCTNUL ;USERF JMP RETNUL ;RESERV1 JMP RETNUL ;RESERV2 JMP APREAD JMP APWRITE boot: lda zpage+8fdh lhld dsktbl dcx h inr a mov m,a ;make slot/drive=boot device MVI A,0C3H STA 30H ;SETUP THE INTERRUPT HANDLER IN APPLE BANK STA 38H P READ JMP WRITE JMP LSTAT JMP SECTRAN JMP LSTAT ;CONOST JMP AUXSTi JMP AUXSTo JMP DEVTBL JMP RETNUL ;DEVINI JMP DRVTBL JMP RETURN ;MULTIO JMP retnul JMP MOVE JMP RETNUL ;TIME JMP SELMEM JMP SETBNK JMP RETURN ;XMOVE JMP RE title 'als cpm card loader bios' ; filename=alsboot.asm ; history ; 8/9/83 modify for first cut of true als ldr bios ; replace jmp at end of warm boot with ret ; 8/10/83 move drive/slot byte to correct position ; (dph0-1) ; 8/11/83 Add correct jrnc selerr ;invalid disk # dad b dad b ;2*disk#=tbl entry mov e,m inx h mov d,m xchg shld curdph ;pointer to current dph ret selerr: LXI H,0 ;THIS CODE IS RUN FOR BAD DISK# RET SECTRAN: MOV H,B ;OUR HARDWARE DOES THE INTERLEABS: EQU IOCB+ 5 ;SECTOR# (00-0FH) IOCBC: EQU IOCB+ 0CH ;COMMAND# (0-3) IOCBR: EQU IOCB+ 0DH ;RETURN STATUS (0-??) IOCBL: EQU IOCB+ 10H ;LAST USED DRIVE# (1-2) IO: EQU ZPAGE-1000H ;IO MEMORY MAP pctlp equ io+9eh ;address of com card init IOBYTE: ;RST7 VECTOR,TOO STA 0 ;ALSO RESET LXI H,INTRPT SHLD 31H SHLD 1 SHLD 39H jmp boot1 ;finish up in common APREAD: APWRITE: SELMEM: RETNUL: XRA A ;RETURN A ZERO FLAG RETURN: RET MOVE: XCHG LDIR XCHG RET setbnk: RET SN'T KILL ADD-RAM APPLA: EQU ZPAGE+045H APPLX: EQU ZPAGE+046H APPLY: EQU ZPAGE+047H APPLST: EQU ZPAGE+048H APPLSP: EQU ZPAGE+049H APPLPC: EQU ZPAGE+3D0H ARWTS: EQU 870H ;6502 ADDRESS OF RWTS DBUFF: EQU ZPAGE+200H ;256 BYTE DISK BUFFER AIOCB: title and filename MACLIB Z80 maclib cpm3 false equ 0 true equ not false cr equ 0dh lf equ 0ah ZPAGE: EQU 07000H ;Z80 ADDRESS OF 6502 PAGE ZERO RAM APPLE: EQU ZPAGE+300H ;Z80 APPLE CALLER ADDRESS APPLE1: EQU APPLE+9 ;Z80 CALLER THAT DOr, return to caller lxi h,dbuff ;zpage+200h lxi b,256 lded dmaad ldir ;move data to dma address xra a ;force no error ret WRITE: ret rwcommon: sta iocbc ;store command in iocb LDA TRACK sta iocbt LDA SECT sta iocbs lda INTER ; D= X X INDEX REGISTER ; E= Y Y INDEX REGISTER ; MSLOT: EQU ZPAGE+7F8H ;CURRENT ACTIVE IO SLOT APPLE: DI ;SNUFF INTERRUPTS MOV C,A ;SAVE THE ACUMULATOR LDA IO+082H ;KILL THE ADD-RAM LDA IO+0FFFH ;KILL ANY ACTIVE I/O ROMS MOV A,H ds 256 DS 32 LSTACK: EQU $ DS 32 WSTACK: EQU $ SPSAVE: DS 2 BCSAVE: DS 2 AFSAVE: DS 2 DMAAD: DS 2 ;CPM R/W 128 BYTE BLOCK ADDRESS DMABNK: DS 1 ;BANK TO DISK READ/WRITE TO/FROM CURBNK: DS 1 ;CURRENTLY SELECTED CPM RUN BANK MYXTPA: DS ) TRACK: DS 2 ;CPM TRACK (0-X) SECT: DS 1 ;CPM SECTOR (0-X) boot1: WBOOT: lxi h,30ch ;set up apple reset vector in add-ram shld 05ffch MVI A,0C3H STA 0 ;SETUP WARM BOOT VECTOR STA 5 ;SETUP BDOS JMP VECTOR STA 30H ;SETUP THE INJMP APPREAD ;READ A BYTE FROM (HL) JMP APPLE1 ;Z80 JMP APPLE (NO MEM KILL) DB 04CH ;65 JMP AARESET DW APRESET JMP APPWRITE ;WRITE 'A' TO (HL) ;********************************* ; ;THE 6502 CAN BE CALLED BY SETTING THESE REGISTERS AND CALLING 't to slot 6 drive 1 for a: dph0: dw 0 db 0 db 0,0,0,0,0,0,0,0,0 dw dpbsd,csv0,alv0 dw dirbcb,dtabcb,-1 db 0 dpbsd dpb 256,16,35,1024,48,3 dirbcb: db 0ffh ;directory bcb db 0,0,0 ;record # db 0 ;wflg db 0 ;spare dw 0 ;track diocbd sta iocbl xra a sta iocbv lhld curdph dcx h mov a,m ani 070h ;get slot # sta iocbsl mov a,m ani 0fh sta iocbd ;set drive # call zrwts ret ;read/write track sector caller zrwts: lxi h,aiocb mov a,h sta appake drive 1(c:) mov m,a lhld dsktbl+6 dcx h inr a mov m,a ;make drive 2(d:) NOTSER: MVI A,0C3H STA 30H ;SETUP THE INTERRUPT HANDLER IN APPLE BANK STA 38H ;RST7 VECTOR,TOO STA 0 ;ALSO RESET LXI H,INTRPT SHLD 31H SHLD 1 SHLD 32 ;COLD BOOT ADDRESS OF BDOS alv0 ds 48 csv0 ds 48 END ndm endm TERRUPT HANDLER IN CPM BANK STA 38H ;SETUP THE DDT VECTOR, TOO LXI H,INTRPT SHLD 31H SHLD 39H LXI H,WBOOTE SHLD 1 ;FORM THE BIOS JMP POINT LDA IOBYTE ;IS THE CONSOLE ONLY 40 COLUMNS? ANI 3 JNZ WBOOT2 WBOOT2: lxi d,80h sta dmaad APPLE' ;THEY ALSO REPRESENT THE 6502 REGISTERS ON RETURN ;DOSN'T USE STACK - CAN BE CALLED FROM WITHIN ADD-RAM ; ;Z80====APPLE ;HL= PC APPLE PROGRAM COUNTER (6502 ADDRESS) ; A= A APPLE ACCUMULATOR ; B= P APPLE STATUS REGISTER ; C= S APPLE STACK POw 0 ;sector dw dirbuf ;buffer address db 0 ;bank dw 0 ;link dirbuf: ds 256 dtabcb: db 0ffh ;data bcb db 0,0,0 ;record # db 0 ;wflg db 0 ;spare dw 0 ;track dw 0 ;sector dw dtabuf ;buffer address db 0 ;bank dw 0 ;link dtabuf:la mov a,l sta apply lxi h,arwts call apple mov a,b ani 01h rz lda iocbr rz ori 0ffh stc ret *** PHYSICAL DISK DRIVE INTERFACE *** ;THESE ARE USED AS THE CPM REQUEST BLOCK - ** KEEP IN ORDER ** DISK: DS 1 ;CPM DRIVE (0-X;Z80 / APPLE HARDWARE RELATED ROUTINES FALSE: EQU 0000 TRUE: EQU NOT FALSE ZPAGE: EQU 07000H ;Z80 ADDRESS OF 6502 ZERO PAGE IO: EQU ZPAGE-1000H ;I/O MEMORY MAP ORG ZPAGE+300H JMP APPLE ;Z80 JMP APPLE DB 04CH ;65 JMP AAPPLE DW APALLP HASH, MY DEBLOCK RET DSKTBL: DW DPH0 dw 0 dw 0 dw 0 DW 0 DW 0 DW 0 DW 0 DW 0 DW 0 DW 0 DW 0 DW 0 DW 0 DW 0 DW 0 ****** DISK ALLOCATION TABLES ****** curdph: dw 0 ;save area for current dph drvslt: db 61h ;defaulret ****** INTERRUPT HANDLER ****** INTRPT: RET ; character i/o device routines CONST: LSTAT: CONIN: ;IS A KEY ALREADY WAITING? CONOUT: LIST: auxin: auxsti: auxout: auxsto: xra a ret DRVTBL: LXI H,DSKTBL ;NO DRIVE TABLE, NO CPI 0C8H ;IS IT IN THE C800 SPACE? JC APPLE5 ;NO - SKIP SPECIAL TREATMENT CPI 0D0H JNC APPLE5 ;NO - SKIP SHLD APPLPC ;SAVE 'HL' LDA MSLOT ;GET THE SLOT (CNH) ADI (IO/256-0C0H)AND 0FFH ;FORM Z80 SLOT ADDRESS(EN OR 6N) MOV H,A MVI L,0 DW 3F2H DB 8DH ;STA PWREDUP DW 3F4H DB 0A9H ;LDA #RESETHI DB 0FAH DB 8DH ;STA #SOFTEV+1 DW 3F3H DB 0ADH ;LDA ADDRAM ;TURN ADDRAM OFF DW 0C082H DB 6CH ;JMP (RESET) DW 0FFFCH APRESET: EQU RESET+OFFSE1 ORG ZPAGE+3D0H APPLPC: D' INSTRUCTION WILL RET TO CALLER OF THIS STUB ; ; OFFSE1: EQU 0-ZPAGE ;(1000H);Z80/6502 ADDRESS OFFSET FOR PROGRAM AREA OFFSE2: EQU ZPAGE+00H ;Z80/6502 ADDRESS OFFSET FOR DATA AREA OFFSE3: EQU IO-0C000H ;(2000H);Z80/6502 ADDRESS OFFSET FOR PERIPHERAL ;SWITCH TO 6502 & SLEEP A WHILE NOP ;WAKE UP TO A NOOP (NEW BOARD NEEDS IT) LXI H,IO+083H ;TURN BACK ON THE ADD-RAM (BANK 2) MOV A,M MOV A,M LDA APPLST ;LOAD ALL OF THE 6502 RESULTS INTO THE Z80 REGISTERS MOV B,A ;NOTE - THE PROGRAM COUNAKE M-SOFT IOCB TABLE AREA ($F380 - $F3AA) ******************* APPREAD: SHLD APPRAD ;READ APPLE(HL) INTO 'A' LXI H,APPLRD CALL APPLE1 RET APPWRITE: SHLD APPWAD ;WRITE 'A' INTO APPLE(HL) STA APPLA LXI H,APPLWR CALL APPLE1 RET APALR 0A6H ;LDX APPLX ;LOAD THE 6502 REGISTERS FROM MEMORY (WHERE THE Z80 PUT THEM) DB APALX DB 0A4H ;LDY APPLY DB APALY DB 0A5H ;LDA APPLST DB APALST DB 48H ;PHA ;SAVE STATUS DB 0A5H ;LDA APPLA DB APALA DB 28H ; MOV A,M ;READ FROM (EN00H) LHLD APPLPC APPLE5: MOV A,C ;APPLE1 WILL NOT KILL THE ADD-RAM OR ANY SLOT ROMS APPLE1: SHLD APPLPC ;STORE ALL OF THE VALUES FOR THE 6502 REGS. INTO MEMORY IF FALSE STA APPLA MOV A,B ;NOTE - THE 6502 STACK POIN ;REGISTER SAVE AREA APALX: EQU 46H APALY: EQU 47H APALST: EQU 48H APALSP: EQU 49H APALPC: EQU 3D0H ENDIF IF FALSE APALA: DS 1 ;REGISTER SAVE AREA APALX: DS 1 APALY: DS 1 APALST: DS 1 APALSP: DS 1 APALPC: DS 2 ENDIF ; ;PROGRAM DA CARDS ; APALJP: EQU APPLJP+OFFSE1 APALLP: EQU APPLLP+OFFSE1 ; ;PROGRAM DATA AREA (AS SEEN BY THE 6502) APALZ4: EQU 0C400H ;ADDRESS OF Z80 CARD#4 (FOR CPU SWAP) APALZ7: EQU 0C700H ;ADDRESS OF Z80 CARD#7 (FOR CPU SWAP) IF TRUE APALA: EQU 45H TER IS NOT RETURNED LDA APPLX MOV D,A LDA APPLY MOV E,A LDA APPLSP MOV C,A LDA APPLA RET ; ; ;THIS IS THE 6502 ROUTINE CALLED BY THE Z80 TO PROCESS THE APPLE 6502 CALLS ;IT IS WRITTEN IN 6502 CODE. -THE Z80 PASSES CONTROL IN THE MIDDLED: DB 0ADH ;LDA APPLOC APPRAD: DW 0 DB 60H ;RTS APALWR: DB 8DH ;STA APPLOC APPWAD: DW 0 DB 60H ;RTS APPLRD: EQU APALRD+OFFSE1 APPLWR: EQU APALWR+OFFSE1 ******************* RESET: DB 0A9H ;LDA #RESETLO DB 62H DB 8DH ;STA SOFTEV PLP ;LOAD STATUS REG DB 20H ;JSR APPLJP ;CALL (INDIRECT) THE REQUESTED 6502 SUBROUTINE DW APALJP DB 4CH ;JMP APPLLP DW APALLP ; APPLJP: DB 6CH ;JMP (APPLPC) ;DO THE 6502 SUBROUTINE ;& RETURN TO CALLER DW APALPC ;'RTSTER IS NOT PASSED STA APPLST MOV A,D STA APPLX MOV A,E STA APPLY ENDIF ; LHLD ZSLOT ;GET THE Z-CARD ADDRESS MOV A,H SUI (IO/256-0C0H)AND 0FFH ;CREATE 6502 VERSION STA ASLOT+1 ;PUT IT INTO 6502 CODE (I KNOW IT'S NOT NICE) MOV M,A TA AREA (AS SEEN BY THE Z80) APPLA: EQU APALA+OFFSE2 ;REGISER SAVE AREA APPLX: EQU APALX+OFFSE2 APPLY: EQU APALY+OFFSE2 APPLST: EQU APALST+OFFSE2 APPLSP: EQU APALSP+OFFSE2 ;********************************* ORG ZPAGE+380H DS 8 ;MAKE ROOM FOR F 68H ;PLA ;GET IT BACK DB 85H ;STA APPLST DB APALST DB 0BAH ;TSX ;GET STACK POINTER DB 86H ;STX APPLSP DB APALSP DB 0A9H,0 ;LDA #$0 ; DB 8DH ;STA Z80 ;START THE Z80 & FREEZE TILL NEXT CALL ASLOT: DW 0 ; DB- ; APPLLP: DB 78H ;SEI ;DISABLE INTERRUPTS DB 86H ;STX APPLX ;SAVE THE 6502 REGISTERS INTO MEMORY (FOR THE Z80 TO SEE) DB APALX DB 84H ;STY APPLY DB APALY DB 85H ;STA APPLA DB APALA DB 08H ;PHP ;SAVE STATUS DBS 2 ;SPACE FOR THE APPLE 6502 VECTOR ORG ZPAGE+3DEH ZSLOT: DW IO+400H ;SIMULATED SOFTCARD LOCATION ORG ZPAGE+3F2H DW APRESET ;SOFT ENTRY VECTOR & POWER-UP BYTE DB 0 END : DW IO+400H ;SIMULATED SOFTCARD LOCATION ORG ZPAGE+3F2H D; A G :ž y! 4 5~yµ5 6y ’ ͒: ! OͻMD2 > BDOS ERR: $Sele @SEC MVI A,88 ;CORRECT FOR THE SLIGHTLY FAST CLOCK BY STA TICK ;(60*62.439)-(60*62)=26.338 TICKS PER MIN LDA @MIN ;STILL FAST BY 1 SEC/3 HOURS ADI 01H ;'INR' WON'T DECIMAL ADJUST PROPERLY DAA STA @MIN CPI 60H JC INTXIT XRA A STA @i - ` ` ` ` ` ` Ø ü ö ` ó ` ` ` Ô Ì b Í Ì Î Ì Ì Ó Í Ì Ì Ì Ì Ì :x*f +20282!_ "1""9- !y2) !f 0 ^#V" !`i`i"y2, `i"* > !r[2 x:* 2x:, 2x:x2x2x* +~p2A ;E.O.F.? RZ ;DONE - READY TO RUN INR A ;WAS THERE AN ERROR? JNZ BOOTERR ;YES - BOMB LXI H,80H DAD D ;BUMP DMA POINTER BY 128 XCHG ;PUT IT IN 'DE' JMP BLOOP2 ;READ IN NEXT SECTOR CCPFCB: DB 1,'CCP COM' DS 23 ****** INT~O !>w:ͨ2 4O.5Ϳ: ! S: ͮ: ͛ͳ: < =! wW* M_S -* MD:" : 2 ɯ2 >G=O* ~~w#~2 ~wc~~p2 !" >2 * ~=2 ~2 ͛o>* wx~2x !|2Ep}2Gp!psx: x7! "_>222028!_ "1"9! ":X 2ɯ!f ɉ a M /  ERRUPT HANDLER ****** INTRPT: IF CLOCK PUSH PSW LDA TICK DCR A STA TICK JNZ INTXIT MVI A,62 ;ACTUAL RATE IS 62.439HZ (1.023MHZ/2E14) STA TICK LDA @SEC ADI 01H ;'DCR' WON'T ADJUST DAA STA @SEC CPI 60H JC INTXIT XRA A STA " r" [  ?, d >l [ I6: <!=6 * J " * K : G/O*  * =d ## I!" 2 =2 !" Û͛o͢͢' ͫ~<7 w@ͩ7: " Û: ~ : 2 : ~ * 6: p w#: w: w*@* }D> $* * T : _2 {2ct$Perm.$ v{_zW{_zW )8# ? w#JJ |^#V###" ##" ######" !  I* ! I* |! 6ʕ67 * w#w* w#w#w! ^#V#Fͪ' O* &! s#r#p* N#F* ^#V#F* : O}|y* %~O !>w:ͨ2 4O.5Ϳ: ! S: ͮ: ͛ͳ: < =! wW* M_S -* MD:" : 2 ɯ2 >G=O* ~~w#~2 ~wc~~p2 !" >2 * ~=2 ~2 ͛o>* w   y2 : xo&: W>O&E: N/* " y2 ʹ͗ͻͫʛ* X: O~Jyʔx ʍ ʂJÍNJ# h2 G>G:~X*  IOw!x>Fwx2 2 ~: : 6: w2 Ji - ` ` ` ` ` ` Ø ü ö ` ó ` ` ` Ô Ì b Í Ì Î Ì Ì Ó Í Ì Ì Ì Ì Ì :x*f +20282!_ "1""9- !y2) !f 0 ^#V" !`i`i"y2, `i"* > !r[2 x:* 2x:, 2x:x2x2x* +~p2+* .}|y#* %* DM"  * s#r* s#r#pyoxgkDM* 0 MD" ! * MD$ : O&! N:  yG>O: ʐÇ* ͒ : ʨn` ~#for2 O͚" }: O* 7" 2 " : O: G2 ! w*  * !UMLK,;~O !>w:ͨ2 4O.5Ϳ: ! S: ͮ: ͛ͳ: < =! wW* M_S -* MD:" : 2 ɯ2 >G=O* ~~w#~2 ~wc~~p2 !" >2 * ~=2 ~2 ͛o>* w!>Z!>2 x"2x:o& ~p2x~2x :2x: 2xͅx: x2 |:K/ * :! ^#V# µ!v Yz>    O a , Readx~2x !|2Ep}2Gp!psx: x7! "_>222028!_ "1"9! ":X 2ɯ!f ɉ a M /  ~2 ~2 : 2 : w: w |g}o' )4: O!3yoxg: O&}* : o$~w{ozg ^#V: ʏ> Û͡" ͳ* ç* r" ! ~#l [ I6: <!=6 * J " * K : G/O*  * =d ## I!" 2 =2 !" Û͛o͢͢' ͫ~<7 w@ͩ7: " Û: ~ : 2 : ~ * 6: p w#: w: w*@* }D> $* * T : _2 {2!" 2 =2 !" Û͛o͢͢' ͫ~<7 w@ͩ7: " Û: ~ : 2 : ~ * 6: p w#: w: w*@* }D> $* * T : _2 {2entify/Initialize' REP 40 * * SlotFinder: This program will identify cards in slots 1-7 * in an Apple ][ or //e. The cards are classified into * six (6) types: * * - Empty (no Cn00 ROM) * - Invalid (Cn00 ROM but not valid) * - Bootable device00 LDY #ZCODELEN-1 ZCMOVE EQU * LDA ZCODELEN*CPMCARD+ZCODE,Y STA 0-ZOFFSET+$9000,Y DEY BPL ZCMOVE * * SETUP BOOT SLOT FOR Z80'S EDIFICATION: * LDA $2B STA BOOTSLOT ;SQUIRREL IT AWAY * * SET CURTRK SO THE Z80'S CORE ROUTINES ARE HAPPY: x~2x !|2Ep}2Gp!psx: x7! "_>222028!_ "1"9! ":X 2ɯ!f ɉ a M /  NHAPPY ;->NOPE JMP SLOTSCAN ;->YES, NOW CHECK OUT I/O * UNHAPPY EQU * DEC Z80SLOT ;(PASSED TO Z80) DEC STORE+2 ;BUMP SLOT LDA STORE+2 CMP #$C1 ;ALL DONE WITH SLOTS? BCS AWESOME ;->KEEP TRYING * * NO CARD. COMPLAIN... * LDX #0 ;INDEX PRI; " r" [  ?, d >l [ I6: <!=6 * J " * K : G/O*  * =d ## IID THE FALSE-READ * WHICH OCCURS ON AN INDIRECT INSTRUCTION. THE FALSE-READ * MIGHT CAUSE PROBLEMS WITH THE Z80, SO WE'LL AVOID IT... * AWESOME EQU * ;JUST LIKE Z'S ON THE ROAD LDA #00 ;Z80 NOP (IT GETS EXECUTED AS LOC 0000) STORE STA $C700 ;SCAN * LSR A ;MAKE 0N LSR A LSR A LSR A TAY LDA $44 ;GET THE HALFTRACK STA $0478,Y ;DRIVE #1 IS THERE LDA #0 STA $04F8,Y ;DRIVE #2 ASSUMED ON ZERO * * SCAN FOR A Z80 CARD, STARTING AT SLOT 7. * * NOTE: THIS IS SELF-MODIFYING CODE TO AVO NT EQU * LDA MESSAGE,X JSR COUT INX CPX #MSGLEN BCC PRINT JMP $FF65 ;OFF TO THE MONITOR * DO CPMCARD MESSAGE ASC '** NO CP/M CARD IN SYSTEM **' ELSE MESSAGE ASC '** NO Z-CARD IN SYSTEM **' FIN MSGLEN EQU *-MESSAGE SBTL 'I/O Card Id SBTL 'Z80 Setup Routines' CHR '-' CrankZ80 EQU * DO CPMCARD * * MOVE THE 6502/Z80 LINKAGE DOWN TO $0300: * LDY #0 MoveIt EQU * LDA $0B00,Y STA $0300,Y INY BNE MoveIt FIN * * Setup the 'unhappy' Z80 code: * ZOFFSET EQU CPMCARD*$80i - ` ` ` ` ` ` Ø ü ö ` ó ` ` ` Ô Ì b Í Ì Î Ì Ì Ó Í Ì Ì Ì Ì Ì :x*f +20282!_ "1""9- !y2) !f 0 ^#V" !`i`i"y2, `i"* > !r[2 x:* 2x:, 2x:x2x2x* +~p2 DOWNWARD * * WE CONTINUE EXECUTION HERE FOR ONE OF THREE REASONS: * 1. THE Z80 DIDN'T START UP; * 2. THE Z80 ISN'T HAPPY (E.G. WRONG Z80 CARD); * 3. THE Z80 IS HAPPY: WE SHOULD JUMP TO $0303. * LDA Z80HAPPY ;IS IT A HAPPY Z80? BEQ UUMLK,; * - Firmware Protocol * - Serial Card Protocol * - Other (try BASIC protocol) * * Entry points are as follows: * * ChkSlot: Given slot# in AC, returns type in AC. * ChkAll : Given ADH in Y, ADL in AC, returns info (AC&Y). * REP 40 * R. BNE NotSerial ;->nope, not serial nor firmware LDY #7 ;check Cn07 for CLC LDA (SlotPtr),Y CMP #$18 ;is it a CLC? BNE NotSerial ;->no, can't be a Serial card * * It appears to be a serial card. Could it be a Firmware card? * LDY #$0B ;look f8-byte info returned * : Y=Hi address * Output : The info * Volatile: none REP 40 * ChkAll EQU * STA InfoPtrL ;setup pointer STY InfoPtrH ; to returned info * * Get info on all 7 slots: * LDY #7 ;start at the top ChkAll2 EQU * TYA ;stN0 DS 1 InitJump DS 3 ;will be JMP-->CnXX DEND * PAGE REP 40 * Scan the I/O slots for card types: REP 40 SlotScan EQU * LDA #>IoTable LDY #scan them slots... REP 40 * Initialize the Cn00 JSR InsDs2 ;disassemble it CMP #$10 ;invalid opcode? BEQ NotBoot ;->invalid; can't boot it * LDY #7 ;check even bytes 00..07 ChkBoot EQU * LDA (SlotPtr),Y ;get a byte CMP DiskId,Y ;check it BNE NotBoot ;->not bootable DEY DEY card, initialize it: * InitSer EQU * CMP #R.Serial ;is it serial? BNE InitNext ;->nope, forget initialization * LDX SlotPtrH ;setup X LDY SlotN0 ;setup Y JSR $C800 ;init the card * InitNext EQU * DEC SlotPtrH ;bump down a slot DEC InitJuEmpty EQU 0 ;Empty slot (no Cn00 ROM) R.Invalid EQU 1 ;Invalid Cn00 ROM R.Boot EQU 2 ;Bootable device R.Firm EQU 3 ;Firmware protocol R.Serial EQU 4 ;Serial card protocol R.Other EQU 5 ;Other: try BASIC protocol * InsDs2 EQU $F88E ;disassembler * iven I/O Slot * Input : AC=slot number 1..7 * Output : AC=Info * Volatile: none REP 40 * ChkSlot EQU * ORA #$C0 ;compute Cn STA SlotPtrH LDA #0 STA SlotPtrL ;make it Cn00 * TYA ;save PHA ; Y * * Check for a Cn00 ROM. If none, then lot-->AC JSR ChkSlot ;get me the info, pal STA (InfoPtr),Y ;return the info DEY ;do next lower slot BNE ChkAll2 ;->more to go * LDA InfoPtrL ;restore AC LDY InfoPtrH ; and Y RTS PAGE REP 40 * Name : ChkSlot * Function: Get info for gI/O Cards: REP 40 LDA #7 ;do slots 7..1 STA SlotCntr * LDA #$4C ;setup JUMP instr STA InitJump LDA #$C7 ;start up at seven STA SlotPtrH STA InitJump+2 LDA #0 STA SlotPtrL * * Setup the pointers and things: * InitSlot EQU * LDA Sl BPL ChkBoot ;do all four bytes LDA #R.Boot ;it's a bootable device JMP ChkExit * * It's not a bootable device. Does it look like a Serial Card? * NotBoot EQU * LDY #5 ;check Cn05 for SEC LDA (SlotPtr),Y ;get the byte CMP #$38 ;is it an SEC? mp+2 DEC SlotCntr BNE InitSlot REP 40 * We're done with the startup stuff. Go back to * where the Z80 wants us to go: REP 40 JMP $0303 PAGE REP 40 * Name : ChkAll * Function: Get info for all 7 I/O slots * Input : AC=Lo address for * Zeropage usage: * DSECT ORG $3C SlotPtr DS 2 ;for accessing slot roms SlotPtrL EQU SlotPtr SlotPtrH EQU SlotPtr+1 InfoPtr DS 2 ;for returned slot info InfoPtrL EQU InfoPtr InfoPtrH EQU InfoPtr+1 SumValue DS 1 ;for CheckRom SlotCntr DS 1 Sloit's EMPTY. * JSR CheckROM ;check for ROM BCC NotEmpty ;=>there's some ROM there LDA #R.Empty ;"empty" JMP ChkExit ;->all done * * OK, so there's a Cn00 ROM. Is it a bootable device? * NotEmpty EQU * LDY #0 LDA (SlotPtr),Y ;get opcode atCntr LDA (InfoPtr),Y ;get card type CMP #R.Firm ;firmware card? BNE InitSer ;->no. maybe serial * * Initialize a firmware card: * LDX SlotPtrH ;setup X LDY SlotN0 ;setup Y JSR InitJump ;go init the card JMP InitNext * * If it's a Serial otPtrH ;construct n0 ASL A ASL A ASL A ASL A STA SlotN0 ; LDA $CFFF ;turn off expansion ROMs LDY #$0D ;offset to INIT byte LDA (SlotPtr),Y ;get init offset STA InitJump+1 ; (assuming Firmware card) * * What kind of card? * LDY Slotor Generic Signature byte LDA (SlotPtr),Y CMP #$01 ;is it a firmware card? BNE SerialC8 ;->regular serial. Validate C8 space. LDA #R.Firm ;say what it is JMP ChkExit * * If it's to be a REAL serial card, there had better be some * ROM in the Name : Sum * Function: Add up 256 bytes * Input : SlotPtr * Output : AC=sum * Volatile: Y REP 40 * Sum EQU * LDY #0 TYA Sum2 EQU * CLC ADC (SlotPtr),Y ;add another byte INY BNE Sum2 RTS * DiskId EQU * ;disk id bytes for "Boot * INC SlotPtrH ;bump pointer to C9xx JSR CheckROM ;check for ROM BCS NotSerial ;->if no C9, then it's OTHER LDA $C9AA ;get the "output" routine JSR InsDs2 ;disassemble it CMP #$10 ;invalid opcode? BEQ NotSerial ;->not a good serial card LD * Checksum the ROM several times, making sure it comes out * the same all times. If not, then it ain't ROM. * JSR Sum ;compute the sum once STA SumValue ;save it * LDX #20 ;that's enough times... CheckROM2 EQU * JSR Sum ;compute the sum againC8 space. * SerialC8 EQU * LDA $CFFF ;turn other C8 ROMs off LDA (SlotPtr),Y ;any Cn turns ours on * LDA #$C8 ;set pointer to C8space STA SlotPtrH * JSR CheckROM ;check for ROM BCS NotSerial ;->if no C8, then it's OTHER LDA $C800 ;get fir Z80SLOT+$7000 ;LD A,(ZPAGE+Z80SLOT) DFB $D6,$60 ;SUB 60H ;MAKE 6n00 DFB $67 ;LD H,A DFB $77 ;LD (HL),A ;HIT ANYWHERE IN Cn00 ZCODELEN EQU *-ZCODE * * FOR CP/M CARD, THIS LOADS AT $1000 FOR UNHAPPY Z-CARD: * DFB $3A DW Z80SLOT+$F000 ;able" DFB 0,$20,0,$00,0,$03,0,$3C ;odds only * * The following Z80 code is moved into the "other" card's * Zeropage area so that it returns to us "unhappy"... * * FOR Z-CARD, THIS LOADS AT $9000 FOR UNHAPPY CP/M-CARD: * ZCODE EQU * DFB $3A DWA #R.Serial ;it really is a serial card JMP ChkExit * * If it isn't SERIAL or FIRMWARE, it's OTHER or INVALID: * NotSerial EQU * LDY #0 LDA (SlotPtr),Y ;get opcode at Cn00 JSR InsDs2 ;disassemble it TAY ;move the mnemonic-index LDA #R.Inva CMP SumValue ;is it stable? BNE NotRom ;->nope, no ROM there... DEX BNE CheckROM2 CLC ;OK JMP ChkRomX ;return * NotRom EQU * SEC ;no dice * ChkRomX EQU * PLA ;restore TAX ; X PLA ; and TAY ; Y PLA ; and AC RTS REP 40 * st byte (Init entry) JSR InsDs2 ;disassemble it CMP #$10 ;invalid opcode? BEQ NotSerial ;->not a good serial card LDA $C84D ;get the "input" routine JSR InsDs2 ;disassemble it CMP #$10 ;invalid opcode? BEQ NotSerial ;->not a good serial card LD A,(ZPAGE+Z80SLOT) DFB $C6,$20 ;ADD 20H ;MAKE En00 DFB $67 ;LD H,A DFB $77 ;LD (HL),A ;HIT ANYWHERE IN Cn00 DS START+768-*,0 ;pad to end of sector 20H ;MAKE En00 DFB $67 ;LD H,A DFB $77 ;LD (HL),A ;HIT ANYWHERE IN Cn00 DSGE REP 40 * Name : CheckROM * Function: Test for 256 bytes of ROM * Input : SlotPtr * Output : Carry CLR if ROM present * : SET if not * Volatile: none REP 40 * CheckROM EQU * PHA ;save AC TYA ; and Y PHA TXA ; and X PHA * lid ;assume invalid CPY #$10 ;invalid opcode? BEQ ChkExit ;->yep, the card's unknown LDA #R.Other ;something else again * ChkExit EQU * STA SlotPtrH ;hold the return code PLA ;restore TAY ; Y LDA SlotPtrH ;restore the return code RTS PAJ H8`?E Vk *f???0xE Hh D#-EEE8` D ܈x D - ܈x8`-0ݩ?ʥD EEE`   vLDczpzqz` [wz` ~~ s L&Y&&Y& 꽌ɪ\8`&&꽌ɪɖ'*&%&,E'зЮ꽌ɪФ`+*xS&x'8*3Ixix&& 8  '  & x)*++`oU~!h:eF)RF)*A>͕B!`͕?!.e>#yR6!Qe> yR6B[ 4*dh^#VoU~!hʣ)*h*h͓Q*h"h!h͆4ʝ)*h"h!h͓4!hͳ4*h"i!i~4pP2e:ih×,i~# )!e6R)*A! `͕?!qe>yR6B[R**A!`͕?!.`HIHHHHhHH݌hHhHh݌H6 ioU!`xQ·-:CiK- 4*>ioU~2e!Jiͅ!e͢R!Liͷ"2Ai:Ai- 4+*>ioUe>GR*e 4*>ioU^#V"V"e*e 4+++*>ioU^#V"V"eY4-94!Bi͌R!Ai6*>i#">i,:Ai-R-*A!$`͕?!e> yR6B[R!>Z!>2 x"2x:o& ~p2x~2x :2x: 2xͅx: x2 |:K/ * :! ^#V# µ!v Yz>    O a , Read(24?949:4<  %%&&'''))*++++,,----...////23334556667777999:::;;;;<<====>>>????+8<(#!*?#>#0#0 >+/!#9!#:!.#&  &&'(((())***,,.000011112223444556 88889 : << >FG8`0($ p,&"_z]` L/慍ꅺL  !"#$%&'()*+,-./0123456789:;<=>?*i^#VoUwR6B[*i^#V+++|!,D*&A!`͕?5=! i͢RB[!we i>ͼQU*>!Ia i>͘5}2 i: i*! i: i_͞Q`R!` i>͘5}2 i! iK͞QG!$i>R!"i*i͌R: i*! iͣQG!e>R!ewe> Rè+! i: iog++M͞QG!e>R! i: ioh@(LH9LHH/Hh/ H-З( ܈(& ˆ$8 H` *HVDP (ED Z $0x8x D- ܈DD#>J>J>VU)?`8'x0|&HhHh VY)'&Y)xꪽ)' `Hh`V0^*^*>&` aI꽌ɪVɭ, Write'5GW^fn Read Error, Drive Error, Volume Mismatch, Write Protect, Init, Bit 2, Bit 1, Bit 0, Retry (Y/N) ?>2Ep>2Gp!ps,!"*(+3111, ).*/ ./3 7??4##+#,,$$ 02<=-.,80^݌Hh Ì Ì݌ Ռ Ռ ՌA ČD Č? ČAEDE?HJ>h Ԍ Ռ Ռ Ռ`HJ>݌h Hh݌`wRO}2e*e:eog"V,>f,>,&A!`͕?5=*i͌RB[*i!e>QR,>*i"h4*i}.R,*A!`͕?!`>yR6B[!Di;)2@i:@i,:e,!Ci6,!Ci6!Ai6!">i*e"Hi*Hi*>i"V/:Aig#ͣQG!'i>R!%i=! i͢R!c i>͘5}2 i: iC+!e i> RÍ+! i: iog+M͞Q!e> ͪQR! i: iog#ͣQ!e > ͪQR!eK> ͪQG!`>Q2e!wee>ͼQ+!ee>R:e2e ,!`e>ͼQ+>2e ,!ewR!we> yR5|+> ,!e:10000000003100012100507E2F77BE280F3AFF7883 :10001000D66032DF733EFF32FE783EFF210303CD10 :100020000073AF4711F8782100631AFE0338073ECA :1000300003B047CDA600CD9E00300C78E60317171D :10004000B01717B047180778F62847CDA600CD9E01 :1000500000300978E6030F0FB04718T STA ZPAGE+0821H ;SAVE IT MVI A,0D8H ;HIGH BYTE OF MOTOR ON TIME COUNT STA ZPAGE+0822H ;SAVE IT MVI A,0EFH ;LOW BYTE OF MOTOR ON TIME COUNT STA ZPAGE+0823H ;SAVE IT MVI B,80H ;INITIALIZE LOOP COUNTER FOR ROM CHECK IF TEST LXI H,0FF65 STA ZPAGE+3DFH ;PUT IT INTO OUR PROGRAM MVI A,0FFH ;TELL BOOT THAT WE TURNED ON STA ZPAGE+8FEH MVI A,0FFH poopout: LXI H,AAPPLE CALL APPLE ;TURN THE 6502 TO OUR WAY OF THINKING.... ;THIS ALSO TURNS THE ADD-RAM ON (FOR NEXT) ; determil2 \r6Fy@D9NPh(o:!k'C@C( dhn2#) )JR8 %#!.ӝO7Ͷ mxruVٶ=6mD5m# BOWpͶ` D/,h>a2C >pC@@s @pemfend$scan listcd: mov a,b ori 040h ;force list=slot 3 mov b,a call scan$other end$scan: mov a,b sta iobyte LDA ZPAGE+8fdH ;GET THE BOOT SLOT# ($N0) STA BIOCB+1 ;PUT IT IN THE IOCB STA BIOCB+0FH ;and last drive used for rwts LXI H,BURRENT IO BOARD SLOT IOCB: EQU ZPAGE+0800H ;ADDRESS OF THE RWTS IO CONTROL BLOCK RESETV: EQU ZPAGE-1004H ;0DFFCH ;6502 RESET VECTOR Z80 ADDRESS ORG 00H start: NOP ;THIS IS A ONE BYTE NOOP - COULD BE ANYTHING LXI SP,STACK ;END OF BOOT AREA lx0778F64047DD :10006000CDA600783203003AFD7832EB0032F90079 :1000700021EA00110078011100EDB021DD001170BE :1000800078010E00EDB0AF3220783E013221783E8B :10009000D83222783EEF3223780680C300012E004A :1000A0001B251AFE03C91AFE05C00E062E057EFE8C :1000B00018201C2Eole=slot 3 ora b mov b,a call scan$other novid: call fixadr ;clean up addrs, test for type 3 jrnc auxcd ;there's an aux card mov a,b ani 3 ral ral ora b ral ral ora b mov b,a ;force auxin/out=console jr noaux auxcd: movne if any 'other' cards in slot table ; if so, test for apple comm type and adjust scan$cards: xra a mov b,a lxi d,slot$table+3 ;start with slot 3 lxi h,io+300h ldax d cpi 3 jrc novid ;slot is empty, invalid or boot mvi a,3 ;set cons title 'zboot for 3.01b bios' maclib z80 ; 7/25/83 mods to use rick's new loader ; and fire up any comm cards found ; also minor code reduction for space ; 8/3/83 correct printer slot iobyte setup, ; picking up boot slot number ; ZBOOT - THIS IOCB ;MOVE BOOT IOCB IN PLACE LXI D,IOCB LXI B,11H ldir LXI H,ZRWTS ;MOVE RWTS CALLER IN PLACE LXI D,7870H LXI B,ZRWTSL ldir XRA A ;SET UP DEVICE TYPE FOR DCT STA ZPAGE+0820H ;SAVE DEVICE TYPE MVI A,1 ;SET UP PHASES PER TRACK FOR DCi h,5000h ;pick a place in boot prom mov A,m cma mov m,a ;test for rom cmp m ;should be different jrz poopout ;not different, wrong z80 card LDA ZPAGE+8ffH ;GET THE CARD LOCATION THAT ABOOT FOUND SUI 60H ;FORM THE Z80 EQUIVILENT ADDRESS 077EFE382015E57C1717171711 :1000C000E6F0F60E26606F36033615E17912C90C9C :1000D0002E053E48BEC02E07BEC07918EF08782016 :1000E000008DB0032818602838600100000000006F :0B00F0002008000200000000000000DB :0000000000  a,b ori 28h ;set auxin/out=slot 2 mov b,a call scan$other ;update for comm type if needed noaux: call fixadr jrnc listcd ;set up card as list ; force list=console mov a,b ani 3 rrc rrc ora b mov b,a ;force list=console jr JUMP TRANSFER PROGRAM AAPPLE: EQU 303H ;APPLE / Z80 6502 JUMP TRANSFER PROGRAM APPLEN: EQU 100H APPLX: EQU ZPAGE+046H APPLY: EQU ZPAGE+047H RWTS: EQU 8800H ;FINAL RWTS PORTION RWLEN: EQU 0100H ;LENGTH OF RWTS CODE TO MOVE MSLOT: EQU ZPAGE+7F8H ;CIS THE FIRST Z80 CODE TO RUN AT BOOT-UP FALSE: EQU 0 TRUE: EQU NOT FALSE TEST EQU FALSE ZPAGE: EQU 07000H IO: EQU ZPAGE-1000H ;I/O MEMORY MAP iobyte equ 3 slot$table equ zpage+8f5h ;rick's slot table APPLE: EQU ZPAGE+300H ;Z80 / APPLE Z80 H ;JMP TO MONITOR JMP APPLE ELSE JMP 100H ;JUMP TO CPMLDR ENDIF fixadr: ;used scanning for cards in 1,2,3 mvi l,0 dcx d dcr h ldax d cpi 3 ret scan$other: ;check other type for apple comm ; enter de:>slottable+n ; hl:>zu wish to copy CPM3.SYS? $Function complete$ERROR: Invalid drive name (Use A, B, C, or D)$ERROR: No source file on disk.$ERROR: No directory space.$ERROR: Out of data space.$ERROR: Write protected?$ERROR: Possible incompatible disk format. Type return toXCOPYRIGHT 1982, DIGITAL RESEARCH151282654321 {__28:7:82!"> 22O* 28:7 scan$par: inr c mvi l,5 mvi a,48h cmp m rnz ;not parallel mvi l,7 cmp m rnz mov a,c jr scan$end$all ZRWTS: EQU $ DB 08 ;PHP DB 78H ;SEI DB 20H,00H,8DH ;JSR $8D00 DB 0B0H,03 ;BCS $087A DB 28H ;PLP DB 18H ;CLC !w# :@!w:!@w23Z<":::o:;g+e:><2>::o:;g":>͉:@w&!y<":::o:;g+ :>=2>::o:;g":Ø ,CPM3 SYS80 equivalent for cn00h ; return zflag=true=apple comm card in slot& inited ; and slot$table updated ldax d cpi 5 rnz ;not other type mvi c,6 ;set for comm type mvi l,5 mov a,m cpi 18h jrnz scan$par ;not comm type mvi l,7 mov a,m  a ^AP0A2A_tA2}  AڤA2A_ !"A>2=!=4:WN>2?:!?4F!?^!FN)y:8>2y2> 22* 28:7:8M>2y2> 22* 28:7:8{x2y2> 22* 28:7:8¡> 22* 28:7:8>22*o&))))))))a{__> > DB 60H ;RTS DB 28H ;PLP DB 38H ;SEC DB 60H ;RTS ZRWTSL: EQU $-ZRWTS+1 BIOCB: DB 1,0,0,0,0,0 dw 820h dw 200h db 0,0,0,0,0,0,0 stkbot equ $ STACK: EQU start+256 stklen equ stack-stkbot END CP/M 3 COPYSYS - Version 3.0$Source drive name (or return for default) $Source on then type return $Destination drive name (or return to reboot) $Destination on then type return $Do yo cpi 38h jrnz scan$par ;not comm type push h mov a,h ral ral ral ral ;gen n0 ani 0f0h ori 0eh ;make it ne mvi h,io/256 ;get 60h mov l,a ;hl=60neh mvi m,3 mvi m,15h ;init comm card pop h scan$end$all: mov a,c stax d ret *ADMX2C:C+ <2C:@<ͬ?͆:*A"A1j D }0t>27y>27:] ʳ\<”Z2|!T]+\Û02@͉!@6Y <0:A_$ ignore.$ERROR: Close operation failed.$y typing SUBMI MAKBOOT FILENAME.EX (wher filename.ex i th fil generated above.) `:S0:@u1 aiꪑ aij` a* ꪑ * j aɊj* 8I8[ N9D 4 s nfPCB`3@7 fo1ɖ%@ZoPfu`:\0fq 9` Bui*i*gi"V/:ji3!"ki!e>@Q!e>@QgQO"i*i*ki"V/:ji3*ri*mi*ki!fi>GR!efixQw3!ji6}3!iD4*ki#"ki43*mi "miY4394!fi͌R!efixQ394!fi͌R3!ji6*gi#"gi3Ã2!i~4pP2eR3*A>͕BB[]^#V#N3]y2]"i:7ͨ8:]!]I89G07!9~#=7*i07Ï?2]2]2]<2]!98 O7+b78o7-o7>2]88҈7~7 ʂ7 %88o7.Ÿ788ҟ7%88Ð7eʩ7E78+¹787-7884VG887xGGG87GyO7 4V87:bi^#VoU^#V"V"e 4+*bi^#VoU`>GRR1*A!D`͕?!e>yR6*e> ͊P6!e>yR6*e> ͊P6!e>yR6B[*bi"di!diE/3 4*e#oU"ti*4~*tiw 4*eoU*ti#>GR 4*eoU*ti >GR*ti 6*ti 6!o 43345|&5|{z5|VDMUog)VT5QY͒5QY!9T+|]533335!!S/<|VFß55O55# 5­55ª5gl6~ 66#WY *@l**@l{ozg4|g}o!\!l!3>3Y!^4* >  3Y3333333333 3Y 33yg)5|g} .*A>͕BB[â.R".*A>͕BB[!"Pi*e"Ri*Ri*Pi"V. 4+*PioU!exQ†.Rz.*A>͕B!+`͕?!e>yR6B[!Tiͥ.!Vi/*Pi#"Pi..R.*A>͕BB[B/^#V"XiRA/*A!0`͕?!e>yR6 4*Xi^#VoU"Zi!Ia>yR!ZiͅSR6 4*Xi] 8%87y2]8~#z0 0!]_w!]~B84_!]s4V4V2]G:]<2]=4V:]4Vͨ8€8:]ʀ8!]5!]44V:]G:]ʎ8!]I8>2]8=!]5š8:]!]<_!]>w w>+ý8!]~5>.9G:]x08:]> !]~85!]4!]5-2R2*A>͕BB[ 4*eoU"vi!vi4!xiv4pP2e*ti#"ri4*e oU"V >@ogU"oi*oi> og-5"oi!ii6!ji6:ji:ii/3!"mi"gi*oi+"zi*zi*gi"V/:ii/2*ri*mi"~i!|i4*mi "mi!i͛42!ii6*gi"oi*gi#"già2!"mi"gi*oi+"5#5H o&H<"~]T6-6BZ!9L6C6~#=36> =C6&9v6x2]y c62]"i:7E=:]+6-/GR 4*`i^#VoU^#V*e"e 4+++*`i^#VoU^#V*e"eR0*A!<`͕?!e>yR6*e> ͊P6!e>yR6*e> ͊P6!e>yR6B[Ì1^#V"bi 4+*bi^#VoU!`xQ1*e 4*bi^#VoU^#V"V"e*e 4+++*^#VoU>yR6!c>yR6 4*Xi^#VoU>yR6B[É/^#V"\i*\i^#V*e"V||/Rq/*A>͕BB[*\i6#6È/*\i^#V#r+s/^#V"^i*^i^#V+|¿/*e*^is#rR/*A>͕BB[/*^i^#V+r+sã0^#V"`i 4+*`i^#VoU!`xQY0 4+*`i^֎ d4 =9=URCONST0ӓ dUUa=URAUXISTUV Tĕ5C1MQPINICTB-M@@%0 a V t_CX0yDpy900 p18H0DPp-A 9#,!ʠ+7/X<0`2B<O-^!@E27E"xFVuC}@vLBNK1 MVI A,0FFH SELBNK1: OUT 0 ENDM SWOUT MACRO SSPD SPSAVE LXI SP,LSTACK push psw mvi a,1 call selmem1 xra a call selmem1 pop psw ENDM SWIN MACRO ;SWITCH BACK TO BANK 1 (CPMCARD) PUSH PSW LDA CURBNK call selmem1 ;sel equ 0ah CPMCARD: EQU TRUE HELLO: EQU FALSE BFILE: EQU TRUE ;IF WARM BOOTING FROM A CPM FILE CLOCK: EQU TRUE ;ENABLE INTERRUPT SYSTEM HARD: EQU FALSE ;IF HARD DISKS ARE INSTALLED BIG: EQU TRUE ;IF EXTRA MEMORY CARD IS INSTALLED COMM: EQU F`:S0:@u1 aiꪑ aij` a* ꪑ * j aɊj* 8I8[ N9D 4 s nfPCB`3@7 fo1ɖ%@ZoPfu`:\0fq 9` BuH) IOCBS: EQU IOCB+ 5 ;SECTOR# (00-0FH) IOCBC: EQU IOCB+ 0CH ;COMMAND# (0-3) IOCBR: EQU IOCB+ 0DH ;RETURN STATUS (0-??) IOCBL: EQU IOCB+ 10H ;LAST USED DRIVE# (1-2) IO: EQU ZPAGE-1000H ;IO MEMORY MAP IOBYTE: EQU 3 BIOS: EQU $ CCP3: EQU 100H g for clr screen ; 8/11/83 add 'NO CCP.COM' msg to warm boot ; change warm boot goto xy clear to blank,cr ; 8/15/83 change sign on to 3.01b ; 9/14/83 change sign on to 3.01b1 ; force momemtary select bank 1 on swout to allow ; a window for interruayy>zD>z`: C;$B0p\. M 8׀ ^Q#n>"9OȌpruFp#^\ Ȋpfg0>GZ=nDS4s<9,>3vW?bfbu$|fȊpj P í\7THAT DOSN'T KILL ADD-RAM APPLA: EQU ZPAGE+045H APPLX: EQU ZPAGE+046H APPLY: EQU ZPAGE+047H APPLST: EQU ZPAGE+048H APPLSP: EQU ZPAGE+049H APPLPC: EQU ZPAGE+3D0H ARWTS: EQU 870H ;6502 ADDRESS OF RWTS DBUFF: EQU ZPAGE+200H ;256 BYTE DISK BUFFER ALSE ;IF APPLE-TYPE COMMCARD DRIVER IS INCLUDED SMARTD: EQU FALSE ;IF IN-CORE SMARTERM 1.X DRIVERS ARE INSTALLED ZPAGE: EQU 07000H ;Z80 ADDRESS OF 6502 PAGE ZERO RAM APPLE: EQU ZPAGE+300H ;Z80 APPLE CALLER ADDRESS APPLE1: EQU APPLE+9 ;Z80 CALLER title 'als cpm card bios' ; main line module ; filename=alsbiosc.asm ; history ; 7/18/83 eliminate all cond garbage ; elim dependence on cp/m 2.2 ; 7/25/83 add aux vectors, reduce use of swout/in ; 7/27/83 minor code reduction ; add test lib EXTRN @MXTPA,@SEC,@MIN,@HOUR,@DATE,@MLTIO,@CNWDT extrn const0,conin0,conout0,list0 extrn auxout0,auxin0,auxist0,auxost0 extrn lstat0 extrn inictbl MEMSEL MACRO ;SWITCHES RAM TO BANK IN ACCUMULATOR LOCAL SELBNK1 ORA A MVI A,0F0H JZ SEpts ; change conin to call constat continuously until ; a character is ready so that interrupt windows ; are available ; 9/15/83 add setting interrupt register to 0ffh MACLIB Z80 maclib cpm3 false equ 0 true equ not false cr equ 0dh lfD*K4sdu~,"7\^yŒ0>Y2K7c̖nY#%^,݊,݊ DZ:wd_WI8[ N9D 4 s nfPCB`3@7 fo1ɖ%@ZoPfu`:\0fq 9` BuAIOCB: EQU 0800H ;6502 ADDRESS OF IOCB IOCB: EQU ZPAGE+AIOCB ;Z80 ADDRESS OF IOCB IOCBSL: EQU IOCB+ 1 ;SLOT*10# (usually 50 OR 60H) IOCBD: EQU IOCB+ 2 ;DRIVE# (1-2) IOCBV: EQU IOCB+ 3 ;VOLUME# (floppies are 00) IOCBT: EQU IOCB+ 4 ;TRACK# (00-22lot 5 use 6 as c&d ; in seldsk, save current dph pointer so rwcommon ; can find slot and drive # of unit ; eliminate @ctbl: in this module ; 8/5/83 correct push/pop reg crossover in write1 ; add sign-on message ; 8/8/83 add form feed to signon msrary ; throw out old disk functions to eliminate ; dependence on dseg module ; correct all dph's, etc to use macros ; 8/4/83 allow pr# to assign 5 or 6 as booted slot ; pick up booted slot # and use for drives a&b ; if slot 6, use 5 as c&d, is s current & ei if allowed&bnk1 POP PSW LSPD SPSAVE ENDM JMP BOOT WBOOTE: JMP WBOOT JMP CONST JMP CONIN JMP CONOUT JMP LIST JMP auxout JMP auxin JMP HOME JMP SELDSK JMP SETTRK JMP SETSEC JMP SETDMA JMP READ JMP WRITE JMall selmem1 push b push d ldir lda curbnk call selmem1 pop h pop b ret ;read/write track sector caller dseg zrwts: mvi e,10 ;retry count zrwts1: push d lxi h,aiocb mov a,h sta appla mov a,l sta apply lxi h,,C sta disk mvi b,0 lxi h,dsktbl ;use table to find dph cpi 16 jrnc selerr ;invalid disk # dad b dad b ;2*disk#=tbl entry mov e,m inx h mov d,m xchg shld curdph ;pointer to current dph ret selerr: LXI H,0 ;THIS CODE IS RUN mov m,a ;second drive=second dph(b:) ani 0f0h ;mask for slot # cpi 60h ;if slot 6 mvi a,50h ;take a chance jrz is$slot$6 mvi a,60h ;first was slot 5, this is slot 6 is$slot$6: lhld dsktbl+4 dcx h inr a ;make drive 1(c:) mov m,a lhldsta iocbl xra a sta iocbv lhld curdph dcx h mov a,m ani 070h ;get slot # sta iocbsl mov a,m ani 0fh sta iocbd ;set drive # call zrwts ret page cseg read1: ;routine for read interbank move lxi d,xferbuf push d pus XRA A ;RETURN A ZERO FLAG RETURN: RET MOVE: XCHG LDIR XCHG RET SELMEM: STA CURBNK selmem1: di push psw MEMSEL pop psw ora a rz push psw lda allowint ora a jrz selmem2 ;do'nt enable intrpts ei selmem2: pop psw RET P LSTAT JMP SECTRAN JMP LSTAT ;CONOST JMP AUXSTi JMP AUXSTo JMP DEVTBL JMP RETNUL ;DEVINI JMP DRVTBL JMP RETURN ;MULTIO JMP retnul JMP MOVE JMP RETNUL ;TIME JMP SELMEM JMP SETBNK JMP RETURN ;XMOVE JMP RETNUL ;USERF JMP RETNUOV L,C SHLD TRACK RET READ: mvi a,1 call rwcommon rnz ;error, return to caller lxi h,dbuff ;zpage+200h lxi b,256 lda dmabnk ora a jnz read1 ;move to buffer first lded dmaad ldir ;move data to dma address xra a ;force no erFOR BAD DISK# RET SECTRAN: MOV H,B ;OUR HARDWARE DOES THE INTERLEAVE TRANSLATION MOV L,C RET SETDMA: MOV H,B MOV L,C SHLD DMAAD RET SETSEC: MOV A,C STA SECT RET HOME: LXI B,0 ;LET SETTRK DO THE ZEROING SETTRK: MOV H,B M dsktbl+6 dcx h inr a mov m,a ;make drive 2(d:) NOTSER: MVI A,0C3H STA 30H ;SETUP THE INTERRUPT HANDLER IN APPLE BANK STA 38H ;RST7 VECTOR,TOO STA 0 ;ALSO RESET LXI H,INTRPT SHLD 31H SHLD 1 SHLD 39H ; display sign-on message h b ldir lda dmabnk call selmem1 ;select dma bank lded dmaad pop b pop h ldir ;move to dma address lda curbnk call selmem1 ;reselect current bank xra a ;force no error ret write1: ;interbank move for write lxi d,xferbuf c SETBNK: STA DMABNK RET DEVTBL: LXI H,ini$ctbl RET BDOS3: LHLD @mxtpa PCHL *** LOGICAL DISK DRIVERS *** ;ALL PHYSICAL OPERATIONS ARE POSTPONED TILL READ/WRITE ;INTERNALLY, DISKS 0&1 ARE FLOPPY, 2&3 ARE HARD dseg SELDSK: MOV AL ;RESERV1 JMP RETNUL ;RESERV2 JMP APREAD JMP APWRITE dseg BOOT: di LXI SP,WSTACK mvi a,0ffh stai ;force ir=0ffh lda zpage+8fdh lhld dsktbl dcx h inr a mov m,a ;put slot/drive in front of dph(a:) inr a lhld dsktbl+2 dcx hror ret WRITE: lhld dmaad lxi b,256 lda dmabnk ora a cnz write1 ;if interbank,first move to buffer lxi d,dbuff ldir mvi a,2 rwcommon: sta iocbc ;store command in iocb LDA TRACK sta iocbt LDA SECT sta iocbs lda iocbd signon: db 0ch,cr,lf,lf,'CP/M 3.01B1 9/15/83' db cr,lf,'Copyright (c) 1983' db cr,lf,'Advanced Logic Systems, Inc.' db cr,lf,lf,0 cseg APREAD: swout CALL APPLE+6 swin RET APWRITE: swout CALL APPLE+0FH swin RET RETNUL: lxi h,signon call con$msg$loop lda iobyte ;pick up zboot's iobyte push psw mvi a,1 jmp boot1 ;finish up in common con$msg$loop: mov a,m ora a rz mov c,a push h lda iobyte call conout0 pop h inx h jmp con$msg$loop arwts call apple mov a,b ani 01h pop d ;get retry count rz lda iocbr ora a rz dcr e jnz zrwts1 ;do it again ori 0ffh stc ret *** PHYSICAL DISK DRIVE INTERFACE *** ;THESE ARE USED AS THE CPM REQUEST BLOCK - ** KEEP IN Oo LIST: lxi h,list0 jr goto auxin: lxi h,auxin0 jr goto auxout: lxi h,auxout0 jr goto auxsti: lxi h,auxist0 jr goto auxsto: lxi h,auxost0 goto: lda iobyte ;get tpa iobyte swout sta iobyte ;and update bank 0 iobyte BDOS LXI D,100H BLOOP2: PUSH D ;SAVE DMA ADDRESS MVI C,1AH ;SET DMA ADDRESS for read CALL BDOS3 LXI D,CCPFCB MVI C,14H ;READ SEQUENTIAL CALL BDOS3 POP D ;RETRIEVE DMA ADDRESS (& STRAIGHTEN STACK) DCR A ;E.O.F.? RZ ;DONE - READ 1982=1826 SHLD @DATE WBOOT: LXI SP,WSTACK xra a sta allowint ;inhibit interrupts for now mvi a,0 call selmem lxi h,30ch ;set up apple reset vector in add-ram shld 05ffch MVI A,1 CALL SELMEM ;SET DEFAULT BANK FOR SWITCHIN MVI STA @HOUR CPI 24H ;HOURS END AT 23:59:59 JC INTXIT XRA A STA @HOUR JC INTXIT PUSH H LHLD @DATE INX H SHLD @DATE POP H INTXIT: POP PSW EI ENDIF RET TICK: DS 1 ;SUB-SECOND COUNTER ; character i/o device routines FILE ***** RDBOOT: LXI H,CCPFCB+12 ;FIRST INIT THE FCB MVI B,22 ;# OF BYTES TO CLEAR BLOOP1: MVI M,0 INX H DCR B JNZ BLOOP1 mvi a,1 call setbnk ;set dma bank to tpa LXI D,80H MVI C,1AH ;SET DMA ADDRESS FOR OPEN COMMAND CALL BDOS3 RDER ** DISK: DS 1 ;CPM DRIVE (0-X) TRACK: DS 2 ;CPM TRACK (0-X) SECT: DS 1 ;CPM SECTOR (0-X) no$ccp$msg: db cr,lf,lf db 'No CCP.COM file on Warm Boot Drive' db cr,lf,'Mount Disk with CCP.COM and press RETURN' db cr,lf,7,0 cseg BO: IF CLOCK PUSH PSW LDA TICK DCR A STA TICK JNZ INTXIT MVI A,62 ;ACTUAL RATE IS 62.439HZ (1.023MHZ/2E14) STA TICK LDA @SEC ADI 01H ;'DCR' WON'T ADJUST DAA STA @SEC CPI 60H JC INTXIT XRA A STA @SEC MVI A,88 ;CORRECT FOR Y TO RUN INR A ;WAS THERE AN ERROR? JNZ BOOTERR ;YES - BOMB LXI H,80H DAD D ;BUMP DMA POINTER BY 128 XCHG ;PUT IT IN 'DE' JMP BLOOP2 ;READ IN NEXT SECTOR CCPFCB: DB 1,'CCP COM' DS 23 ****** INTERRUPT HANDLER ****** INTRPT A,0C3H STA 0 ;SETUP WARM BOOT VECTOR STA 5 ;SETUP BDOS JMP VECTOR STA 30H ;SETUP THE INTERRUPT HANDLER IN CPM BANK STA 38H ;SETUP THE DDT VECTOR, TOO LXI H,INTRPT SHLD 31H SHLD 39H mvi a,0ffh sta allowint ei LXI H,WBOOTE SHLD 1 CONST: lxi h,CONST0 jr goto LSTAT: lxi h,lstat0 jr goto CONIN: ;IS A KEY ALREADY WAITING? call const jrz conin ;cause interrupt 'windows' till ; character available lxi h,CONIN0 jr goto CONOUT: lxi h,conout0 jr gotMVI E,05 MVI C,2DH ;RETURN BDOS ERROR MODE TO DEFAULT CALL BDOS3 MVI A,1 STA @MLTIO LXI D,CCPFCB ;OPEN THE CCP FILE MVI C,0FH ;OPEN FILE CALL BDOS3 ANI 0FCH ;OPEN ERROR? JNZ BOOTERR ;YES - BOMB ; SHOULD BE IN BANK 1 NOW BECAUSE OF OTERR: LXI SP,WSTACK lxi h,no$ccp$msg swout call con$msg$loop swin boot$err1: call conin cpi cr jrnz boot$err1 ;wait for return jr wboot boot1: call selmem pop psw sta iobyte ;and put in tpa bank LXI H,2008 ;DECEMBER 31,THE SLIGHTLY FAST CLOCK BY STA TICK ;(60*62.439)-(60*62)=26.338 TICKS PER MIN LDA @MIN ;STILL FAST BY 1 SEC/3 HOURS ADI 01H ;'INR' WON'T DECIMAL ADJUST PROPERLY DAA STA @MIN CPI 60H JC INTXIT XRA A STA @MIN LDA @HOUR ADI 01H DAA BDOS JMP POINT MVI C,' ' ;CLEAR ANY PENDING GOTOXY'S CALL CONOUT MVI C,cr CALL CONOUT CALL RDBOOT ;GET CCP INTO MEMORY lxi d,80h MVI C,1AH ;SET DMA ADDRESS CALL BDOS3 JMP CCP3 ***** GET THE CPM3 CCP PROGRAM INTO CORE FROM A ;FORM THE BIOS JMP POINT LDA IOBYTE ;IS THE CONSOLE ONLY 40 COLUMNS? ANI 3 mvi a,80 JNZ WBOOT2 MVI A,40 WBOOT2: STA @CNWDT ;TELL BDOS HOW WIDE THE SCREEN IS LHLD @MXTPA ;GET THE JUMP ADDRESS FROM SYSTEM CONTROL BLOCK SHLD 6 ;FORM THE call ipchl swin ret ipchl: pchl DRVTBL: LXI H,DSKTBL ;NO DRIVE TABLE, NO HASH, MY DEBLOCK RET DSKTBL: DW DPH0 DW DPH1 dw dph2 dw dph3 DW 0 DW 0 DW 0 DW 0 DW 0 DW 0 DW 0 DW 0 DW 0 DW 0 DW 0 DW 0 ****** DIS>J>J>VU)?`8'x0|&HhHh VY)'&Y)xꪽ)' `Hh`V0^*^*>&` aI꽌ɪVɭff  =B CL =B =EAL>? >>?` =J>J>VU)?`8'x0|&HhHh VY)'&Y)xꪽ)' `Hh`V0^*^*>&` aI꽌ɪVɭLl <8M<E <Ll ϱ<ȅ= s *  M = s  Ll < =h=`HHH @ @L 8hhh`q<` <:x`gw: gw ENDING: EQU $ END  BOOT ADDRESS OF BDOS xferbuf: ds 256 ;interbank buffer ;FLOPPY DISK SECTOR ALLOCATION VECTORS BANK MYXTPA: DS 2 ;COLD BOOT ADDRESS OF BDOS xferbuf: ds 256 ;interbank buffer ;FLOPPY DISK SECTOR ALLOCATION VECTORS Ll <8M<E <Ll ϱ<ȅ= s *  M = s  Ll < =h=`HHH @ @L 8hhh`q<` <:x`gw: gwrmac alsboot $$abrblbszpz-m link a:cpmldr=a:cpmldr,b:alsboot mac apple $$ablbszpzhb-m mac zboot $$ablbszpzhb-m sid O&E: N/* " y2 ʹ͗ͻͫʛ* X: O~Jyʔx ʍ ʂJÍNJ# h2 G>G:~X*  IOw!x>Fwx2 2 ~: : 6: w2 1  ͍ %͍͍ʢ͏͕!~# 4͕ ͍:g:s:_g:s!]~$o#~B̩1ɷW|g ͏͕%z͍͍ ͍vCPM3 SYS CPMLDR error: failed to open CPM3.SYS $ CPML!"*(+3111, ).*/ ./3 7??4##+#,,$$ 02<=-.,80^݌Hh Ì Ì݌ Ռ Ռ ՌA ČD Č? ČAEDE?HJ>h Ԍ Ռ Ռ Ռ`HJ>݌h Hh݌`+* .}|y#* %* DM"  * s#r* s#r#pyoxgkDM* 0 MD" ! * MD$ : O&! N:  yG>O: ʐÇ* ͒ : ʨn` ~#for2 O͚" }: O* 7" 2 " : O: G2 ! w*  * !sL\Ès5sLÒsO:`:o|4s4s"s:wƠg.~*sy"s*s|֠2nsw!`~~:HpG:FpW:Gp_:IpO:EpxFGEhHIFGHHE( L\l"s!5s"s2Ep!5sɭ``bldFG8`0($ p,&"_z]` L/慍ꅺL  !"#$%&'()*+,-./0123456789:;<=>?; A G :ž y! 4 5~yµ5 6y ’ ͒: ! OͻMD2 > BDOS ERR: $SeleDR error: failed to read CPM3.SYS $ CP/M V3.0 Loader Copyright (C) 1982, Digital Research $021182" yڥ2 2 : 2 {2 !" " 9"@1!N y2K!dڛ_^#V*    HIHHHHhHH݌hHhHh݌H6  Û͡" ͳ* ç* r" ! ~#2x>!sGx!c8>Gͦ͞0 xGx(Gͦ͞0 xGx@Gͦx2:x22!x!px2 x>2!x>2"x>2#x.%.~ .~8 |&`o66y .>H.yx (`(8` (24?949:4<  %%&&'''))*++++,,----...////23334556667777999:::;;;;<<====>>>????+8<(#!*?#>#0#0 >+/!#9!#:!.#&  &&'(((())***,,.000011112223444556 88889 : << >ct$Perm.$ v{_zW{_zW )8# ? w#JJ |^#V###" ##" ######" !  I* ! I* |! 6ʕ67 * w#w* w#w#w! ^#V#Fͪ' O* &! s#r#p* N#F* ^#V#F* : O}|y* % H8`?E Vk *f???0xE Hh D#-EEE8` D ܈x D - ܈x8`-0ݩ?ʥD EEE`   vLDczpzqz` [wz` ~~ s Lh@(LH9LHH/Hh/ H-З( ܈(& ˆ$8 H` *HVDP (ED Z $0x8x D- ܈DD#~O !>w:ͨ2 4O.5Ϳ: ! S: ͮ: ͛ͳ: < =! wW* M_S -* MD:" : 2 ɯ2 >G=O* ~~w#~2 ~wc~~p2 !" >2 * ~=2 ~2 ͛o>* wwRO}2e*e:eog"V,>f,>,&A!`͕?5=*i͌RB[*i!e>QR,>*i"h4*i}.R,*A!`͕?!`>yR6B[!Di;)2@i:@i,:e,!Ci6,!Ci6!Ai6!">i*e"Hi*Hi*>i"V/:AiJi - ` ` ` ` ` ` Ø ü ö ` ó ` ` ` Ô Ì b Í Ì Î Ì Ì Ó Í Ì Ì Ì Ì Ì :x*f +20282!_ "1""9- !y2) !f 0 ^#V" !`i`i"y2, `i"* > !r[2 x:* 2x:, 2x:x2x2x* +~p2*i^#VoUwR6B[*i^#V+++|!,D*&A!`͕?5=! i͢RB[!we i>ͼQU*>!Ia i>͘5}2 i: i*! i: i_͞Q`R!` i>͘5}2 i! iK͞QG!$i>R!"i*i͌R: i*! iͣQG!e>R!ewe> Rè+! i: iog++M͞QG!e>R! i: ioUMLK,;!" 2 =2 !" Û͛o͢͢' ͫ~<7 w@ͩ7: " Û: ~ : 2 : ~ * 6: p w#: w: w*@* }D> $* * T : _2 {2, Write'5GW^fn Read Error, Drive Error, Volume Mismatch, Write Protect, Init, Bit 2, Bit 1, Bit 0, Retry (Y/N) ?>2Ep>2Gp!ps,!>Z!>2 x"2x:o& ~p2x~2x :2x: 2xͅx: x2 |:K/ * :! ^#V# µ!v Yz>    O a , Readx~2x !|2Ep}2Gp!psx: x7! "_>222028!_ "1"9! ":X 2ɯ!f ɉ a M /  g#ͣQG!'i>R!%i=! i͢R!c i>͘5}2 i: iC+!e i> RÍ+! i: iog+M͞Q!e> ͪQR! i: iog#ͣQ!e > ͪQR!eK> ͪQG!`>Q2e!wee>ͼQ+!ee>R:e2e ,!`e>ͼQ+>2e ,!ewR!we> yR5|+> ,!e; " r" [  ?, d >l [ I6: <!=6 * J " * K : G/O*  * =d ## IoU~!h:eF)RF)*A>͕B!`͕?!.e>#yR6!Qe> yR6B[ 4*dh^#VoU~!hʣ)*h*h͓Q*h"h!h͆4ʝ)*h"h!h͓4!hͳ4*h"i!i~4pP2e:ih×,i~# )!e6R)*A! `͕?!qe>yR6B[R**A!`͕?!.` - 4+*>ioU!`xQ·-:CiK- 4*>ioU~2e!Jiͅ!e͢R!Liͷ"2Ai:Ai- 4+*>ioUe>GR*e 4*>ioU^#V"V"e*e 4+++*>ioU^#V"V"eY4-94!Bi͌R!Ai6*>i#">i,:Ai-R-*A!$`͕?!e> yR6B[R!"*(+3111, ).*/ ./3 7??4##+#,,$$ 02<=-.,80^݌Hh Ì Ì݌ Ռ Ռ ՌA ČD Č? ČAEDE?HJ>h Ԍ Ռ Ռ Ռ`HJ>݌h Hh݌`5#5H o&H<"~]T6-6BZ!9L6C6~#=36> =C6&9v6x2]y c62]"i:7E=:]+6-/GR 4*`i^#VoU^#V*e"e 4+++*`i^#VoU^#V*e"eR0*A!<`͕?!e>yR6*e> ͊P6!e>yR6*e> ͊P6!e>yR6B[Ì1^#V"bi 4+*bi^#VoU!`xQ1*e 4*bi^#VoU^#V"V"e*e 4+++*N8}ԑY%9>8TS#b8TԐ#I58PUc_!=UJ8RSM8TT#_5aQA8'P#_ =9]&85ӕ# =918SSWY *@l**@l{ozg4|g}o!\!l!3>3Y!^4* >  3Y3333333333 3Y 33yg)5|g} .*A>͕BB[â.R".*A>͕BB[!"Pi*e"Ri*Ri*Pi"V. 4+*PioU!exQ†.Rz.*A>͕B!+`͕?!e>yR6B[!Tiͥ.!Vi/*Pi#"Pi..R.*A>͕BB[B/^#V"XiRA/*A!0`͕?!e>yR6 4*Xi^#VoU"Zi!Ia>yR!ZiͅSR6 4*Xi] 8%87y2]8~#z0 0!]_w!]~B84_!]s4V4V2]G:]<2]=4V:]4Vͨ8€8:]ʀ8!]5!]44V:]G:]ʎ8!]I8>2]8=!]5š8:]!]<_!]>w w>+ý8!]~5>.9G:]x08:]> !]~85!]4!]5-2]y2]"i:7ͨ8:]!]I89G07!9~#=7*i07Ï?2]2]2]<2]!98 O7+b78o7-o7>2]88҈7~7 ʂ7 %88o7.Ÿ788ҟ7%88Ð7eʩ7E78+¹787-7884VG887xGGG87GyO7 4V87:bi^#VoU^#V"V"e 4+*bi^#VoU`>GRR1*A!D`͕?!e>yR6*e> ͊P6!e>yR6*e> ͊P6!e>yR6B[*bi"di!diE/3 4*e#oU"ti*4~*tiw 4*eoU*ti#>GR 4*eoU*ti >GR*ti 6*ti 6(24?949:4<  %%&&'''))*++++,,----...////23334556667777999:::;;;;<<====>>>????+8<(#!*?#>#0#0 >+/!#9!#:!.#&  &&'(((())***,,.000011112223444556 88889 : << >!o 43345|&5|{z5|VDMUog)VT5QY͒5QY!9T+|]533335!!S/<|VFß55O55# 5­55ª5gl6~ 66#^#VoU>yR6!c>yR6 4*Xi^#VoU>yR6B[É/^#V"\i*\i^#V*e"V||/Rq/*A>͕BB[*\i6#6È/*\i^#V#r+s/^#V"^i*^i^#V+|¿/*e*^is#rR/*A>͕BB[/*^i^#V+r+sã0^#V"`i 4+*`i^#VoU!`xQY0 4+*`i^Рd4dT8 =Y@AIVECSՑPddT8 9- @CRDMAd5$E4Y%9>@RESEL dU5$4HI5@DATEPTDԔM?ERJMPV`T$H =9]&@CNWDTӓ`dD@8EUPㄟ =Y8MRUP=Y8UՑPㆿ 9- 8yԑPc 1i*i*gi"V/:ji3!"ki!e>@Q!e>@QgQO"i*i*ki"V/:ji3*ri*mi*ki!fi>GR!efixQw3!ji6}3!iD4*ki#"ki43*mi "miY4394!fi͌R!efixQ394!fi͌R3!ji6*gi#"gi3Ã2!i~4pP2eR3*A>͕BB[]^#V#N3R2*A>͕BB[ 4*eoU"vi!vi4!xiv4pP2e*ti#"ri4*e oU"V >@ogU"oi*oi> og-5"oi!ii6!ji6:ji:ii/3!"mi"gi*oi+"zi*zi*gi"V/:ii/2*ri*mi"~i!|i4*mi "mi!i͛42!ii6*gi"oi*gi#"già2!"mi"gi*oi+"HIHHHHhHH݌hHhHh݌H6 O: ʐÇ* ͒ : ʨn` ~#for2 O͚" }: O* 7" 2 " : O: G2 ! w*  * !1!P~/w(:x`2s>2x>!sGx!c8>Gͦ͞0 xGx(Gͦ͞0 xGx@Gͦx2:x22!x!px2 x>2!x>2"x>2#x.%.~ .~8 |&`o66y .>H.yx (`(8` !" 2 =2 !" Û͛o͢͢' ͫ~<7 w@ͩ7: " Û: ~ : 2 : ~ * 6: p w#: w: w*@* }D> $* * T : _2 {2; A G :ž y! 4 5~yµ5 6y ’ ͒: ! OͻMD2 > BDOS ERR: $Seleh@(LH9LHH/Hh/ H-З( ܈(& ˆ$8 H` *HVDP (ED Z $0x8x D- ܈DD#  y2 : xo&: W>O&E: N/* " y2 ʹ͗ͻͫʛ* X: O~Jyʔx ʍ ʂJÍNJ# h2 G>G:~X*  IOw!x>Fwx2 2 ~: : 6: w2 ~2 ~2 : 2 : w: w |g}o' )4: O!3yoxg: O&}* : o$~w{ozg ^#V: ʏ> Û͡" ͳ* ç* r" ! ~#l [ I6: <!=6 * J " * K : G/O*  * =d ## Ict$Perm.$ v{_zW{_zW )8# ? w#JJ |^#V###" ##" ######" !  I* ! I* |! 6ʕ67 * w#w* w#w#w! ^#V#Fͪ' O* &! s#r#p* N#F* ^#V#F* : O}|y* % H8`?E Vk *f???0xE Hh D#-EEE8` D ܈x D - ܈x8`-0ݩ?ʥD EEE`   vLDczpzqz` [wz` ~~ s L~O !>w:ͨ2 4O.5Ϳ: ! S: ͮ: ͛ͳ: < =! wW* M_S -* MD:" : 2 ɯ2 >G=O* ~~w#~2 ~wc~~p2 !" >2 * ~=2 ~2 ͛o>* wDR error: failed to read CPM3.SYS $ CP/M V3.0 Loader Copyright (C) 1982, Digital Research $021182" yڥ2 2 : 2 {2 !" " 9"@1!N y2K!dڛ_^#V*    1  ͍ %͍͍ʢ͏͕!~# 4͕ ͍:g:s:_g:s!]~$o#~B̩1ɷW|g ͏͕%z͍͍ ͍vCPM3 SYS CPMLDR error: failed to open CPM3.SYS $ CPML